{"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","execution":{"iopub.status.busy":"2022-07-03T10:40:48.363861Z","iopub.execute_input":"2022-07-03T10:40:48.364384Z","iopub.status.idle":"2022-07-03T10:40:48.405665Z","shell.execute_reply.started":"2022-07-03T10:40:48.364271Z","shell.execute_reply":"2022-07-03T10:40:48.404816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In this competition, you'll write an algorithm to classify whether images contain either a dog or a cat.\n\nThis Competion contains 25000 Training Images of either Dog/Cat. Each image contains 224-Pixels\n\n**Each image is having 3 Channels / Layers i.e Red-channel, Green-channel and Blue-channel. Each Pixel in each Channel each has a Pixel-intensity value between 0 & 255. These 224-Pixels are our Features and their values are Feature Values to train our Model**\n\nThis is how 'computer-sees', also called ***Computer Vision***. I also will not do much Feature Engineering as it may lead to TAMPERED Data","metadata":{}},{"cell_type":"markdown","source":"A colored image is typically composed of multiple colors and almost all colors can be generated from three primary colors – red, green and blue.\n\nHence, in the case of a colored image, there are three Matrices (or channels) – Red, Green, and Blue. Each matrix has values between 0-255 representing the intensity of the color for that pixel. Consider the below image to understand this concept:\n\n![RGB-Image](https://cdn.analyticsvidhya.com/wp-content/uploads/2019/08/article-image-41.png)","metadata":{}},{"cell_type":"markdown","source":"## **Get Image Pixels**\n\nColor images are represented as three-dimensional Numpy arrays - a collection of three two-dimensional arrays, one each for red, green, and blue channels. Each one, like grayscale arrays, has one value per pixel and their ranges are identical.\n\n![rgb](https://e2eml.school/images/image_processing/three_d_array.png)","metadata":{}},{"cell_type":"markdown","source":"## **Convolution Operation**\n\nThe fundamental difference between a densely connected layer and a convolution layer is this: Dense layers learn global patterns in their input feature space (for example, for a MNIST digit, patterns involving all pixels), whereas convolution layers learn local patterns in the case of images, patterns found in small 2D windows of the inputs.\n\n**This key characteristic gives convnets two interesting properties:**\n1. The patterns they learn are translation invariant. After learning a certain pattern in the lower-right corner of a picture, a convnet can recognize it anywhere: forexample, in the upper-left corner. A densely connected network would have to learn the pattern anew if it appeared at a new location.\n1. They can learn spatial hierarchies of patterns (see figure 5.2). A first convolution layer will learn small local patterns such as edges, a second convolution layer will learn larger patterns made of the features of the first layers, and so on. This allows convnets to efficiently learn increasingly complex and abstract visual concepts (because the visual world is fundamentally spatially hierarchical).","metadata":{}},{"cell_type":"markdown","source":"# **Import Basic Libraries**\n\n**more to be imported as needed**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport PIL\nimport PIL.Image\n\nimport tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:40:57.005739Z","iopub.execute_input":"2022-07-03T10:40:57.006269Z","iopub.status.idle":"2022-07-03T10:41:01.301590Z","shell.execute_reply.started":"2022-07-03T10:40:57.006233Z","shell.execute_reply":"2022-07-03T10:41:01.300870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Load Data**","metadata":{}},{"cell_type":"code","source":"train_dir = \"../input/dogs-vs-cats/train.zip\"\n\nimport zipfile\nwith zipfile.ZipFile(train_dir, \"r\") as f:\n    f.extractall('.')","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:41:07.806537Z","iopub.execute_input":"2022-07-03T10:41:07.806788Z","iopub.status.idle":"2022-07-03T10:41:19.229057Z","shell.execute_reply.started":"2022-07-03T10:41:07.806761Z","shell.execute_reply":"2022-07-03T10:41:19.228281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# File Path\nIMAGE_FOLDER_PATH = \"../working/train\"\nFILE_PATH = [os.path.join(IMAGE_FOLDER_PATH,i) for i in os.listdir(IMAGE_FOLDER_PATH)]\n\n# Labels\nlabels=[i for i in os.listdir(IMAGE_FOLDER_PATH)]\n\n# Targets\ntargets=[i.split('.')[0] for i in labels]\ny=targets\n\n# Dataframe\ndata = pd.DataFrame({'PATH':FILE_PATH,'targets':targets}) \ndata","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:41:19.232296Z","iopub.execute_input":"2022-07-03T10:41:19.232501Z","iopub.status.idle":"2022-07-03T10:41:19.330376Z","shell.execute_reply.started":"2022-07-03T10:41:19.232476Z","shell.execute_reply":"2022-07-03T10:41:19.329591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Train-Val Split**","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df, val_df = train_test_split(data, test_size=0.20, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:41:19.332083Z","iopub.execute_input":"2022-07-03T10:41:19.332337Z","iopub.status.idle":"2022-07-03T10:41:19.616931Z","shell.execute_reply.started":"2022-07-03T10:41:19.332302Z","shell.execute_reply":"2022-07-03T10:41:19.616015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Train Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator()\n\ntrain=datagen.flow_from_dataframe(dataframe=train_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\ntrain","metadata":{"execution":{"iopub.status.busy":"2022-07-02T19:16:32.295447Z","iopub.execute_input":"2022-07-02T19:16:32.29608Z","iopub.status.idle":"2022-07-02T19:16:32.486905Z","shell.execute_reply.started":"2022-07-02T19:16:32.296038Z","shell.execute_reply":"2022-07-02T19:16:32.486127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.class_indices","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:09.99621Z","iopub.execute_input":"2022-07-01T17:44:09.996944Z","iopub.status.idle":"2022-07-01T17:44:10.006779Z","shell.execute_reply.started":"2022-07-01T17:44:09.996898Z","shell.execute_reply":"2022-07-01T17:44:10.003672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Validation Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator()\n\nval=datagen.flow_from_dataframe(dataframe=val_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\nval","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:10.008357Z","iopub.execute_input":"2022-07-01T17:44:10.008665Z","iopub.status.idle":"2022-07-01T17:44:10.076068Z","shell.execute_reply.started":"2022-07-01T17:44:10.008629Z","shell.execute_reply":"2022-07-01T17:44:10.075421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val.class_indices","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:10.078764Z","iopub.execute_input":"2022-07-01T17:44:10.078948Z","iopub.status.idle":"2022-07-01T17:44:10.086911Z","shell.execute_reply.started":"2022-07-01T17:44:10.078925Z","shell.execute_reply":"2022-07-01T17:44:10.086019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **EDA - Further Analysis of Data**","metadata":{}},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:15.518681Z","iopub.execute_input":"2022-07-01T17:44:15.519161Z","iopub.status.idle":"2022-07-01T17:44:15.541307Z","shell.execute_reply.started":"2022-07-01T17:44:15.519121Z","shell.execute_reply":"2022-07-01T17:44:15.540635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['targets'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:15.544001Z","iopub.execute_input":"2022-07-01T17:44:15.544281Z","iopub.status.idle":"2022-07-01T17:44:15.5541Z","shell.execute_reply.started":"2022-07-01T17:44:15.54425Z","shell.execute_reply":"2022-07-01T17:44:15.553416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualize the Data**","metadata":{}},{"cell_type":"markdown","source":"## Image-Gallery Function","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import load_img\n\ndef gallery(nrow,ncol,name):    # This function creates a grid of images from  dataset.\n    \n    img_df = train_df[train_df['targets'] == name]   # little data sorting\n    path_df = img_df['PATH']\n    \n    # Gallery using Matplotlib \n    fig, ax = plt.subplots(nrow,ncol,figsize = (12,12), dpi = 100)\n    axes = ax.ravel()\n    \n    for idx,ax  in enumerate(axes):\n        ax.imshow(load_img(path_df.iloc[idx]))\n    return fig.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:15.555196Z","iopub.execute_input":"2022-07-01T17:44:15.555625Z","iopub.status.idle":"2022-07-01T17:44:15.565742Z","shell.execute_reply.started":"2022-07-01T17:44:15.555532Z","shell.execute_reply":"2022-07-01T17:44:15.565078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gallery(5,5,name='cat')","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:15.566843Z","iopub.execute_input":"2022-07-01T17:44:15.567257Z","iopub.status.idle":"2022-07-01T17:44:18.180439Z","shell.execute_reply.started":"2022-07-01T17:44:15.567221Z","shell.execute_reply":"2022-07-01T17:44:18.17965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gallery(5,5,name='dog')","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:18.181522Z","iopub.execute_input":"2022-07-01T17:44:18.181794Z","iopub.status.idle":"2022-07-01T17:44:20.615992Z","shell.execute_reply.started":"2022-07-01T17:44:18.181752Z","shell.execute_reply":"2022-07-01T17:44:20.615174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Simple CNN + MaxPooling**\n\nImportantly, a CNN takes as input tensors of shape (image_height, image_width,image_channels)\n\n* **Conv2D-**This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 3) for 128x128 RGB pictures in data_format=\"channels_last\". You can use None when a dimension has variable size.\n\nConvolutions are defined by two key parameters:\n1. Size of the patches extracted from the inputs—These are typically 3 × 3 or 5 × 5. Here they were 3 × 3, which is a common choice.\n1. Depth of the output feature map—The number of filters computed by the convolution.\n\nA convolution works by sliding these windows of size 3 × 3 or 5 × 5 over the 3D input feature map, stopping at every possible location, and extracting the 3D patch of surrounding features (shape (window_height, window_width, input_depth)). Each such 3D patch is then transformed (via a tensor product with the same learned weight matrix, called the convolution kernel) into a 1D vector of shape (output_depth,). All of\nthese vectors are then spatially reassembled into a 3D output map of shape (height,width, output_depth). Every spatial location in the output feature map corresponds to the same location in the input feature map (for example, the lower-right corner of the output contains information about the lower-right corner of the input). For instance, with 3 × 3 windows, the vector output[i, j, :] comes from the 3D patch input[i-1:i+1, j-1:j+1, :]. \n\n![cnn](https://miro.medium.com/max/1400/1*vkQ0hXDaQv57sALXAJquxA.jpeg)\n\n* **MaxPool2D-**Downsamples the input along its spatial dimensions (height and width) by taking the maximum value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.\n\nMax pooling consists of extracting windows from the input feature maps and outputting the max value of each channel. It’s conceptually similar to convolution, except that instead of transforming local patches via a learned linear transformation (the convolution kernel), they’re transformed via a hardcoded max tensor operation. A big difference from convolution is that max pooling is usually done with 2 × 2 windows and","metadata":{}},{"cell_type":"markdown","source":"## **Build the Model**","metadata":{}},{"cell_type":"code","source":"from keras.layers import Conv2D,MaxPool2D\nfrom keras.models import Sequential\n\nmodel1 = Sequential()\n\nmodel1.add(Conv2D(32,(3,3),activation='relu',input_shape=(224,224,3))),\nmodel1.add(MaxPool2D((2,2))),\n\nmodel1.add(Conv2D(64,(3,3),activation='relu')),\nmodel1.add(MaxPool2D((2,2))),\n\nmodel1.add(Conv2D(128,(3,3),activation='relu')),\nmodel1.add(MaxPool2D((2,2))),\n\nmodel1.add(Conv2D(256,(3,3),activation='relu')),\nmodel1.add(MaxPool2D((2,2))),\n\nmodel1.add(Conv2D(256,(3,3),activation='relu')),\nmodel1.add(MaxPool2D((2,2))),\n\nmodel1.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:20.617475Z","iopub.execute_input":"2022-07-01T17:44:20.617723Z","iopub.status.idle":"2022-07-01T17:44:23.936514Z","shell.execute_reply.started":"2022-07-01T17:44:20.617692Z","shell.execute_reply":"2022-07-01T17:44:23.934909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **+ Dense + Flatten**","metadata":{}},{"cell_type":"markdown","source":"**You can see that the output of every Conv2D and MaxPooling2D layer is a 3D tensor of shape (height, width, channels). The width and height dimensions tend to shrink. As you go deeper in the network. The number of channels is controlled by the first argument passed to the Conv2D layers (32 or 64).**\n\n**The next step is to feed the last output tensor into a densely connected classifier network : a stack of Dense layers. These classifiers process vectors, which are 1D, whereas the current output is a\n3D tensor. First we have to flatten the 3D outputs to 1D, and then add a few Dense layers on top**\n\n* **Flatten-**Flattens the input. Does not affect the batch size.\n\n* **Dense-**Dense implements the operation: output = activation(dot(input, kernel) + bias) where activation is the element-wise activation function passed as the activation argument, kernel is a weights matrix created by the layer, and bias is a bias vector created by the layer (only applicable if use_bias is True). These are all attributes of Dense.","metadata":{}},{"cell_type":"code","source":"from keras.layers import Conv2D,MaxPool2D,Flatten,Dense\n   \nmodel1.add(Flatten()),\nmodel1.add(Dense(1024,activation='relu')),\nmodel1.add(Dense(256,activation='relu')),\nmodel1.add(Dense(32,activation='relu')),\nmodel1.add(Dense(1,activation='sigmoid')),\n\nmodel1.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:23.95119Z","iopub.execute_input":"2022-07-01T17:44:23.951429Z","iopub.status.idle":"2022-07-01T17:44:24.008791Z","shell.execute_reply.started":"2022-07-01T17:44:23.951396Z","shell.execute_reply":"2022-07-01T17:44:24.008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting**","metadata":{}},{"cell_type":"code","source":"!pip install visualkeras\nimport visualkeras\nvisualkeras.layered_view(model1, legend=True) ","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:36.264374Z","iopub.execute_input":"2022-07-01T17:44:36.264639Z","iopub.status.idle":"2022-07-01T17:44:36.475948Z","shell.execute_reply.started":"2022-07-01T17:44:36.264608Z","shell.execute_reply":"2022-07-01T17:44:36.475243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(model1, 'model.png',show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:36.47898Z","iopub.execute_input":"2022-07-01T17:44:36.481596Z","iopub.status.idle":"2022-07-01T17:44:37.511795Z","shell.execute_reply.started":"2022-07-01T17:44:36.481555Z","shell.execute_reply":"2022-07-01T17:44:37.510992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Compile**","metadata":{}},{"cell_type":"code","source":"model1.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.1),\n                loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),\n                metrics=tf.keras.metrics.BinaryAccuracy())","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:37.513735Z","iopub.execute_input":"2022-07-01T17:44:37.514019Z","iopub.status.idle":"2022-07-01T17:44:37.535946Z","shell.execute_reply.started":"2022-07-01T17:44:37.513983Z","shell.execute_reply":"2022-07-01T17:44:37.535291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Train**","metadata":{}},{"cell_type":"code","source":"history1=model1.fit(train,  \n                   epochs=5,\n                    #     verbose=\"auto\",\n                    #     callbacks=tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3) # This callback will stop the training when there is no improvement in the loss for three consecutive epochs.,\n                    #     validation_split=0.0,\n                            validation_data=val,\n                            shuffle=True,\n                    #     class_weight=None,\n                    #     sample_weight=None,\n                    #     initial_epoch=0,\n                    #     steps_per_epoch=None,\n                    #     validation_steps=None,\n                    #     validation_batch_size=None,\n                    #     validation_freq=1,\n                    #     max_queue_size=10,\n                    #     workers=1,\n                    #     use_multiprocessing=False,\n                    )","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:44:37.537349Z","iopub.execute_input":"2022-07-01T17:44:37.537598Z","iopub.status.idle":"2022-07-01T17:52:23.718288Z","shell.execute_reply.started":"2022-07-01T17:44:37.537565Z","shell.execute_reply":"2022-07-01T17:52:23.717512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting Accuracy**","metadata":{}},{"cell_type":"code","source":"# summarize history for accuracy\nplt.plot(history1.history['binary_accuracy'])\nplt.plot(history1.history['val_binary_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:52:23.719736Z","iopub.execute_input":"2022-07-01T17:52:23.720063Z","iopub.status.idle":"2022-07-01T17:52:23.925985Z","shell.execute_reply.started":"2022-07-01T17:52:23.720025Z","shell.execute_reply":"2022-07-01T17:52:23.92531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Horrible, My friends at Kaggle could have done much better Guessing**","metadata":{}},{"cell_type":"markdown","source":"# **+ Padding + Strides**\n\n**Padding-**If you want to get an output feature map with the same spatial dimensions as the input, you can use padding. Padding consists of adding an appropriate number of rows and columns on each side of the input feature map so as to make it possible to fit center convolution windows around every input tile. For a 3 × 3 window, you add one column on the right, one column on the left, one row at the top, and one row at the bottom. For a 5 × 5 window, you add two rows \n\n\n**Strides-**The description of convolution so far has assumed that the center tiles of the convolution windows are all contiguous. But the distance between two successive windows is a parameter of the convolution, called its stride, which defaults to 1. It’s possible to have strided convolutions: convolutions with a stride higher than 1\n\n![cnn-padding-stride](https://jehyunlee.github.io/2020/11/29/Python-DL-1-conv2d/keras_conv2d_padding.gif)","metadata":{}},{"cell_type":"markdown","source":"## **Build Model**","metadata":{}},{"cell_type":"code","source":"from keras.layers import Conv2D,MaxPool2D,Flatten,Dense\nfrom keras.models import Sequential\n\nmodel2 = Sequential()\n\nmodel2.add(Conv2D(filters=32,kernel_size=3,strides=(3,3),padding='same',activation='relu',input_shape=(224,224,3))),\nmodel2.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel2.add(Conv2D(filters=64,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel2.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel2.add(Conv2D(filters=128,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel2.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel2.add(Conv2D(filters=256,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel2.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel2.add(Conv2D(filters=256,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel2.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel2.add(Flatten()),\nmodel2.add(Dense(units=1024,activation='relu')),\nmodel2.add(Dense(units=256,activation='relu')),\nmodel2.add(Dense(units=32,activation='relu')),\nmodel2.add(Dense(units=1,activation='sigmoid')),\n\nmodel2.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:52:23.927299Z","iopub.execute_input":"2022-07-01T17:52:23.927666Z","iopub.status.idle":"2022-07-01T17:52:24.029617Z","shell.execute_reply.started":"2022-07-01T17:52:23.92763Z","shell.execute_reply":"2022-07-01T17:52:24.028939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Visualize**","metadata":{}},{"cell_type":"code","source":"!pip install visualkeras\nimport visualkeras\nvisualkeras.layered_view(model2, legend=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:52:24.03338Z","iopub.execute_input":"2022-07-01T17:52:24.033568Z","iopub.status.idle":"2022-07-01T17:52:24.062649Z","shell.execute_reply.started":"2022-07-01T17:52:24.033545Z","shell.execute_reply":"2022-07-01T17:52:24.061988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(model1, 'model.png',show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:52:24.063655Z","iopub.execute_input":"2022-07-01T17:52:24.063901Z","iopub.status.idle":"2022-07-01T17:52:24.265966Z","shell.execute_reply.started":"2022-07-01T17:52:24.063864Z","shell.execute_reply":"2022-07-01T17:52:24.265186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Compile & Train**","metadata":{}},{"cell_type":"code","source":"# Model Compile\nmodel2.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.1),\n                loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),\n                metrics=tf.keras.metrics.BinaryAccuracy())\n\n\n# Train\nhistory2=model2.fit(train,  \n                   epochs=5,\n                    #     verbose=\"auto\",\n                    #     callbacks=tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3) # This callback will stop the training when there is no improvement in the loss for three consecutive epochs.,\n                    #     validation_split=0.0,\n                    validation_data=val,\n                    shuffle=True,\n                    #     class_weight=None,\n                    #     sample_weight=None,\n                    #     initial_epoch=0,\n                    #     steps_per_epoch=None,\n                    #     validation_steps=None,\n                    #     validation_batch_size=None,\n                    #     validation_freq=1,\n                    #     max_queue_size=10,\n                    #     workers=1,\n                    #     use_multiprocessing=False,\n                    )","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:52:24.267684Z","iopub.execute_input":"2022-07-01T17:52:24.268333Z","iopub.status.idle":"2022-07-01T17:58:48.523154Z","shell.execute_reply.started":"2022-07-01T17:52:24.268293Z","shell.execute_reply":"2022-07-01T17:58:48.522452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting**","metadata":{}},{"cell_type":"code","source":"# Comparing Accuracy\nplt.plot(history2.history['val_binary_accuracy'],'b')\nplt.plot(history1.history['val_binary_accuracy'],'r')\nplt.title('binary_ accuracy')\nplt.ylabel('val_binary_accuracy')\nplt.xlabel('epoch')\nplt.legend(['model1', 'model2'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:58:48.526417Z","iopub.execute_input":"2022-07-01T17:58:48.526777Z","iopub.status.idle":"2022-07-01T17:58:48.819814Z","shell.execute_reply.started":"2022-07-01T17:58:48.52675Z","shell.execute_reply":"2022-07-01T17:58:48.819047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**So little improvement that even Matplotlib cannot pick**","metadata":{}},{"cell_type":"markdown","source":"# **+ Data Augmentation**\n\nData augmentation takes the approach of generating more training data from existing training samples, by augmenting the samples via a number of random transformations that yield believable-looking images. The goal is that at training time, your model will never see the exact same picture twice. This helps expose the model to more aspects of the data and generalize better.\n\nImage augmentation is a technique of applying different transformations to original images which results in multiple transformed copies of the same image. Each copy, however, is different from the other in certain aspects depending on the augmentation techniques you apply like shifting, rotating, flipping, etc.\n\nApplying these small amounts of variations on the original image does not change its target class but only provides a new perspective of capturing the object in real life. And so, we use it is quite often for building deep learning models.\n\nThese image augmentation techniques not only expand the size of your dataset but also incorporate a level of variation in the dataset which allows your model to generalize better on unseen data. Also, the model becomes more robust when it is trained on new, slightly altered images.","metadata":{}},{"cell_type":"markdown","source":"## **Train Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator(\n#     featurewise_center=True,\n#     samplewise_center=T,\n#     featurewise_std_normalization=False,\n#     samplewise_std_normalization=False,\n#     zca_whitening=True,\n#     zca_epsilon=1e-06,\n#     rotation_range=90,\n#     width_shift_range=0.5,\n#     height_shift_range=0.5,\n#     brightness_range=None,\n#     shear_range=0.0,\n#     zoom_range=0.0,\n#     channel_shift_range=0.0,\n#     fill_mode='nearest',\n#     cval=0.0,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rescale=1./255,\n#     preprocessing_function=None,\n#     data_format=None,\n#     validation_split=0.0,\n#     interpolation_order=1,\n#     dtype=None\n)\n\ntrain=datagen.flow_from_dataframe(dataframe=train_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\ntrain","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:06:10.714888Z","iopub.execute_input":"2022-07-01T18:06:10.715353Z","iopub.status.idle":"2022-07-01T18:06:10.914868Z","shell.execute_reply.started":"2022-07-01T18:06:10.715315Z","shell.execute_reply":"2022-07-01T18:06:10.914107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The Keras ImageDataGenerator class is not an “additive” operation. It’s not taking the original data, randomly transforming it, and then returning both the original data and transformed data. Instead, the ImageDataGenerator accepts the original data, randomly transforms it, and returns only the new, transformed data.**","metadata":{}},{"cell_type":"markdown","source":"## **Validation Data**","metadata":{}},{"cell_type":"code","source":"val=datagen.flow_from_dataframe(dataframe=val_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\nval","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:06:21.043144Z","iopub.execute_input":"2022-07-01T18:06:21.043473Z","iopub.status.idle":"2022-07-01T18:06:21.103705Z","shell.execute_reply.started":"2022-07-01T18:06:21.043432Z","shell.execute_reply":"2022-07-01T18:06:21.103005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Build Model**","metadata":{}},{"cell_type":"code","source":"# Build Model\n\nmodel3 = Sequential()\n\nmodel3.add(Conv2D(filters=32,kernel_size=3,strides=(3,3),padding='same',activation='relu',input_shape=(224,224,3))),\nmodel3.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel3.add(Conv2D(filters=64,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel3.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel3.add(Conv2D(filters=128,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel3.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel3.add(Flatten()),\n\nmodel3.add(Dense(units=1,activation='sigmoid')),\n\nmodel3.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:06:26.251084Z","iopub.execute_input":"2022-07-01T18:06:26.251606Z","iopub.status.idle":"2022-07-01T18:06:29.193151Z","shell.execute_reply.started":"2022-07-01T18:06:26.251566Z","shell.execute_reply":"2022-07-01T18:06:29.192396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Visualize**","metadata":{}},{"cell_type":"code","source":"!pip install visualkeras\nimport visualkeras\nvisualkeras.layered_view(model3, legend=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:07:51.0148Z","iopub.execute_input":"2022-07-01T18:07:51.015483Z","iopub.status.idle":"2022-07-01T18:07:51.072938Z","shell.execute_reply.started":"2022-07-01T18:07:51.015443Z","shell.execute_reply":"2022-07-01T18:07:51.072168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(model3, 'model.png',show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:08:00.996358Z","iopub.execute_input":"2022-07-01T18:08:00.996655Z","iopub.status.idle":"2022-07-01T18:08:02.210131Z","shell.execute_reply.started":"2022-07-01T18:08:00.996621Z","shell.execute_reply":"2022-07-01T18:08:02.20929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Compile & Train**","metadata":{}},{"cell_type":"code","source":"# Model Compile\nmodel3.compile(optimizer='adam',\n                loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),\n                metrics=tf.keras.metrics.BinaryAccuracy())\n\n# Train\nhistory3=model3.fit(train,  \n                   epochs=10,\n                    #     verbose=\"auto\",\n                    #     callbacks=tf.keras.callbacks.EarlyStopping(monitor='val_binary_accuracy', patience=3) # This callback will stop the training when there is no improvement in the loss for three consecutive epochs.,\n#                         validation_split=0.2,\n                    validation_data=val,\n                    shuffle=True,\n                    #     class_weight=None,\n                    #     sample_weight=None,\n                    #     initial_epoch=0,\n                    #     steps_per_epoch=None,\n                    #     validation_steps=None,\n                    #     validation_batch_size=None,\n                    #     validation_freq=1,\n                    #     max_queue_size=10,\n                    #     workers=1,\n                    #     use_multiprocessing=False,\n                    )","metadata":{"execution":{"iopub.status.busy":"2022-07-01T19:06:10.570338Z","iopub.execute_input":"2022-07-01T19:06:10.570598Z","iopub.status.idle":"2022-07-01T19:32:58.791521Z","shell.execute_reply.started":"2022-07-01T19:06:10.57057Z","shell.execute_reply":"2022-07-01T19:32:58.788514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting**","metadata":{}},{"cell_type":"code","source":"# Comparing Accuracy\nplt.plot(history3.history['binary_accuracy'],'b')\nplt.plot(history3.history['val_binary_accuracy'],'b-')\n# plt.plot(history1.history['val_binary_accuracy'],'b*'')\n# plt.title('Model Accuracy Comparison')\n# plt.xlabel('epoch')\n# plt.legend(['model3', 'model2','model1'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T17:58:49.798613Z","iopub.status.idle":"2022-07-01T17:58:49.800375Z","shell.execute_reply.started":"2022-07-01T17:58:49.799938Z","shell.execute_reply":"2022-07-01T17:58:49.800134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Bit better considering only 10-epochs**","metadata":{}},{"cell_type":"markdown","source":"# **+Regularization**\nRegularizers allow you to apply penalties on layer parameters or layer activity during optimization. These penalties are summed into the loss function that the network optimizes.\n\nRegularization penalties are applied on a per-layer basis. The exact API will depend on the layer, but many layers (e.g. Dense, Conv1D, Conv2D and Conv3D) have a unified API.\n\nThese layers expose 3 keyword arguments:\n\n* kernel_regularizer: Regularizer to apply a penalty on the layer's kernel\n* bias_regularizer: Regularizer to apply a penalty on the layer's bias\n* activity_regularizer: Regularizer to apply a penalty on the layer's output\n\n1. **Data Augmentation-**The simplest way to reduce overfitting is to increase the size of the training data. In machine learning, we were not able to increase the size of training data as the labeled data was too costly.\n\nBut, now let’s consider we are dealing with images. In this case, there are a few ways of increasing the size of the training data – rotating the image, flipping, scaling, shifting, etc. In the below image, some transformation has been done on the handwritten digits dataset.\n![data-aug](https://cdn.analyticsvidhya.com/wp-content/uploads/2018/04/Screen-Shot-2018-04-04-at-12.14.45-AM.png)\nThis technique is known as data augmentation. This usually provides a big leap in improving the accuracy of the model. It can be considered as a mandatory trick in order to improve our predictions.\n\n2. **Dropout-**Dropout means that during training with some probability P a neuron of the neural network gets turned off during training. Let’s look at a visual example. A simpler version of the neural network results in less complexity that can reduce overfitting. The deactivation of neurons with a certain probability P is applied at each forward propagation and weight update step.\n\n![dropout](https://cdn.analyticsvidhya.com/wp-content/uploads/2018/04/1IrdJ5PghD9YoOyVAQ73MJw.gif)\n\n3. **Early stopping-**Early stopping is one of the most commonly used strategies because it is very simple and quite effective. It refers to the process of stopping the training when the training error is no longer decreasing but the validation error is starting to rise.\n\n![early-stopping](https://cdn.analyticsvidhya.com/wp-content/uploads/2018/04/Screen-Shot-2018-04-04-at-12.31.56-AM.png)\n\n4. **Batch Normalization-**Batch normalization (BN) can also be used as a form of regularization. Batch normalization fixes the means and variances of the input by bringing the feature in the same range.\n\n![bn](https://theaisummer.com/static/d42512016d9b99eabb69a61bb295cd50/2e9f9/normalization.png)","metadata":{}},{"cell_type":"markdown","source":"## **Train Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator(\n#     featurewise_center=True,\n#     samplewise_center=True,\n#     featurewise_std_normalization=False,\n#     samplewise_std_normalization=False,\n#     zca_whitening=True,\n#     zca_epsilon=1e-06,\n#     rotation_range=90,\n#     width_shift_range=0.5,\n#     height_shift_range=0.5,\n#     brightness_range=None,\n#     shear_range=0.0,\n    zoom_range=0.5,\n#     channel_shift_range=0.0,\n#     fill_mode='nearest',\n#     cval=0.0,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rescale=1./255,\n#     preprocessing_function=None,\n#     data_format=None,\n#     validation_split=0.0,\n#     interpolation_order=1,\n#     dtype=None\n)\n\ntrain=datagen.flow_from_dataframe(dataframe=train_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\ntrain","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:21:19.819333Z","iopub.execute_input":"2022-07-02T16:21:19.819997Z","iopub.status.idle":"2022-07-02T16:21:20.018677Z","shell.execute_reply.started":"2022-07-02T16:21:19.819959Z","shell.execute_reply":"2022-07-02T16:21:20.017942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Validation Data**","metadata":{}},{"cell_type":"code","source":"val=datagen.flow_from_dataframe(dataframe=val_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\nval","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:21:29.589537Z","iopub.execute_input":"2022-07-02T16:21:29.590087Z","iopub.status.idle":"2022-07-02T16:21:29.648096Z","shell.execute_reply.started":"2022-07-02T16:21:29.590047Z","shell.execute_reply":"2022-07-02T16:21:29.647366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Build Model**","metadata":{}},{"cell_type":"code","source":"from keras.layers import Conv2D, MaxPool2D, Dropout, Flatten, Dense, Activation, BatchNormalization\nfrom keras.models import Sequential\nfrom tensorflow.keras import regularizers\n\nmodel4 = Sequential()\n\nmodel4.add(Conv2D(filters=32,kernel_size=3,strides=(3,3),padding='same',activation='relu',input_shape=(224,224,3))),\nmodel4.add(BatchNormalization())\nmodel4.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\nmodel4.add(Dropout(0.25))\n\nmodel4.add(Conv2D(filters=64,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel4.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\nmodel4.add(Conv2D(filters=128,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\nmodel4.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n\n# flatten output of conv\nmodel4.add(Flatten())\n\n# hidden layer\nmodel4.add(Dense(512, activation='relu', kernel_regularizer=regularizers.L1L2(l1=0.001,l2=0.001))) # Added Regularization\nmodel4.add(Dropout(0.25))\n\n# output layer\nmodel4.add(Dense(1, activation='sigmoid'))\n\nmodel4.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:21:36.654406Z","iopub.execute_input":"2022-07-02T16:21:36.654673Z","iopub.status.idle":"2022-07-02T16:21:39.547063Z","shell.execute_reply.started":"2022-07-02T16:21:36.654643Z","shell.execute_reply":"2022-07-02T16:21:39.546368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Visualize**","metadata":{}},{"cell_type":"code","source":"!pip install visualkeras\nimport visualkeras\nvisualkeras.layered_view(model4, legend=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:21:47.595072Z","iopub.execute_input":"2022-07-02T16:21:47.595328Z","iopub.status.idle":"2022-07-02T16:22:00.98039Z","shell.execute_reply.started":"2022-07-02T16:21:47.5953Z","shell.execute_reply":"2022-07-02T16:22:00.979673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(model4, 'model.png',show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:22:01.896188Z","iopub.execute_input":"2022-07-02T16:22:01.896455Z","iopub.status.idle":"2022-07-02T16:22:02.883952Z","shell.execute_reply.started":"2022-07-02T16:22:01.896427Z","shell.execute_reply":"2022-07-02T16:22:02.883147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Compile & Callback & Train**","metadata":{}},{"cell_type":"code","source":"# Model Compile\nmodel4.compile(optimizer='adam',\n                loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),\n                metrics=tf.keras.metrics.BinaryAccuracy())\n\n# Callbacks\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nes=tf.keras.callbacks.EarlyStopping(monitor='val_binary_accuracy', patience=3) # This callback will stop the training when there is no improvement in the loss for three consecutive epochs.,\nlrr = ReduceLROnPlateau(monitor='val_binary_accuracy',patience=2) \ncb = [es, lrr]\n\n# Train\nhistory4=model4.fit(train,  \n                   epochs=20,\n                    #     verbose=\"auto\",\n                        callbacks=cb, \n                    #     validation_split=0.2,\n                    validation_data=val,\n                    shuffle=True,\n                    #     class_weight=None,\n                    #     sample_weight=None,\n                    #     initial_epoch=0,\n                    #     steps_per_epoch=None,\n                    #     validation_steps=None,\n                    #     validation_batch_size=None,\n                    #     validation_freq=1,\n                    #     max_queue_size=10,\n                    #     workers=1,\n                    #     use_multiprocessing=False,\n                    )","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:22:12.192887Z","iopub.execute_input":"2022-07-02T16:22:12.193515Z","iopub.status.idle":"2022-07-02T16:22:41.141254Z","shell.execute_reply.started":"2022-07-02T16:22:12.193476Z","shell.execute_reply":"2022-07-02T16:22:41.138369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Save Model**","metadata":{}},{"cell_type":"code","source":"# Saving Model\nmodel4.save('cat_vs_dog_model.h5')","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:22:41.142067Z","iopub.status.idle":"2022-07-02T16:22:41.142355Z","shell.execute_reply.started":"2022-07-02T16:22:41.142204Z","shell.execute_reply":"2022-07-02T16:22:41.142224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting**","metadata":{}},{"cell_type":"code","source":"# summarize history for accuracy\nplt.plot(history4.history['binary_accuracy'])\nplt.plot(history4.history['val_binary_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-02T16:22:41.149273Z","iopub.status.idle":"2022-07-02T16:22:41.151277Z","shell.execute_reply.started":"2022-07-02T16:22:41.151035Z","shell.execute_reply":"2022-07-02T16:22:41.151061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Transfer Learning**\n\nTransfer learning is a machine learning method where we reuse a pre-trained model as the starting point for a model on a new task.\n\n**To put it simply—a model trained on one task is repurposed on a second, related task as an optimization that allows rapid progress when modeling the second task. By applying transfer learning to a new task, one can achieve significantly higher performance than training with only a small amount of data.**\n\nTransfer learning is so common that it is rare to train a model for an image or natural language processing-related tasks from scratch.\n\n![tl](https://assets-global.website-files.com/5d7b77b063a9066d83e1209c/616b35e31e352613b291f4c7_P46neY1rhMd5NbTxhCbaWWAnwJwhgCZjSLp2C2-6Pzf8sBEfAxtlhnAOV_Jq_gX-zOaztDWLrtFal42V-EDr86Gcd8QYrWh4uMxZ-_-X_Pd5tOge9EkBmFr7UxrEWLMwCNZi14WK%3Ds0.jpeg)\n\nTensorFlow Hub is an online repository of already trained TensorFlow models that you can use. These models can either be used as is, or they can be used for Transfer Learning. Transfer learning is a process where you take an existing trained model, and extend it to do additional work. This involves leaving the bulk of the model unchanged, while adding and retraining the final layers, in order to get a different set of possible outputs.\n\n![tl2](https://miro.medium.com/max/1000/0*xNjEPIZmPvKeqss6)","metadata":{}},{"cell_type":"markdown","source":"**The model that we'll use is MobileNet v2 (but any model from tf2 compatible image classifier URL from tfhub.dev would work).**","metadata":{}},{"cell_type":"markdown","source":"## **Train Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator(\n#     featurewise_center=True,\n#     samplewise_center=True,\n#     featurewise_std_normalization=False,\n#     samplewise_std_normalization=False,\n#     zca_whitening=True,\n#     zca_epsilon=1e-06,\n#     rotation_range=90,\n#     width_shift_range=0.5,\n#     height_shift_range=0.5,\n#     brightness_range=None,\n#     shear_range=0.0,\n    zoom_range=0.5,\n#     channel_shift_range=0.0,\n#     fill_mode='nearest',\n#     cval=0.0,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rescale=1./255,\n#     preprocessing_function=None,\n#     data_format=None,\n#     validation_split=0.0,\n#     interpolation_order=1,\n#     dtype=None\n)\n\ntrain=datagen.flow_from_dataframe(dataframe=train_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\ntrain","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:41:49.267498Z","iopub.execute_input":"2022-07-03T10:41:49.267757Z","iopub.status.idle":"2022-07-03T10:41:50.338733Z","shell.execute_reply.started":"2022-07-03T10:41:49.267728Z","shell.execute_reply":"2022-07-03T10:41:50.337808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Validation Data**","metadata":{}},{"cell_type":"code","source":"val=datagen.flow_from_dataframe(dataframe=val_df,\n                                     x_col=\"PATH\",\n                                     y_col=\"targets\",\n                                     target_size=(224, 224),\n                                     class_mode=\"binary\")\n\nval","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:42:31.576708Z","iopub.execute_input":"2022-07-03T10:42:31.576981Z","iopub.status.idle":"2022-07-03T10:42:31.635860Z","shell.execute_reply.started":"2022-07-03T10:42:31.576951Z","shell.execute_reply":"2022-07-03T10:42:31.635119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Download MobileNet**\n\nDownload the MobileNet model and create a Keras model from it. **MobileNet** is expecting images of 224 $\\times$ 224 pixels, in 3 color channels (RGB).\n\nWith transfer learning we reuse parts of an already trained model and change the final layer, or several layers, of the model, and then retrain those layers on our own dataset.\n\nIn addition to complete models, TensorFlow Hub also distributes models without the last classification layer. These can be used to easily do transfer learning.\n\n*Note that we're calling the partial model from TensorFlow Hub (without the final classification layer) a `feature_extractor`. The reasoning for this term is that it will take the input all the way to a layer containing a number of features. So it has done the bulk of the work in identifying the content of an image, except for creating the final probability distribution. That is, it has extracted the features of the image.*\n\n![mobilenetv2](https://ars.els-cdn.com/content/image/1-s2.0-S2210670720309070-gr4.jpg)","metadata":{}},{"cell_type":"code","source":"import tensorflow_hub as hub\nmobilenet =\"https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/2\"\nfeature_extractor = hub.KerasLayer(mobilenet,input_shape=(224,224,3))\n\n# Freeze the variables in the feature extractor layer, so that the training only modifies the final classifier layer.\nfeature_extractor.trainable = False","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:42:37.872527Z","iopub.execute_input":"2022-07-03T10:42:37.872779Z","iopub.status.idle":"2022-07-03T10:42:39.189298Z","shell.execute_reply.started":"2022-07-03T10:42:37.872750Z","shell.execute_reply":"2022-07-03T10:42:39.188424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Build Model**","metadata":{}},{"cell_type":"code","source":"from keras.models import Sequential\nfrom tensorflow.keras.layers import Dense\n\nmodel5 = tf.keras.Sequential()\n\nmodel5.add(feature_extractor),\nmodel5.add(Dense(1, activation='sigmoid'))\n\nmodel5.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:42:44.370809Z","iopub.execute_input":"2022-07-03T10:42:44.371369Z","iopub.status.idle":"2022-07-03T10:42:44.582959Z","shell.execute_reply.started":"2022-07-03T10:42:44.371323Z","shell.execute_reply":"2022-07-03T10:42:44.582226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Compile & Train**","metadata":{}},{"cell_type":"code","source":"# Model Compile\nmodel5.compile(optimizer='adam',\n                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n                metrics=tf.keras.metrics.BinaryAccuracy())\n\n# Train\nhistory5=model5.fit(train,  \n                   epochs=10,\n                    #     verbose=\"auto\",\n                    #     callbacks=cb, \n                    #     validation_split=0.2,\n                    validation_data=val,\n                    shuffle=True,\n                    #     class_weight=None,\n                    #     sample_weight=None,\n                    #     initial_epoch=0,\n                    #     steps_per_epoch=None,\n                    #     validation_steps=None,\n                    #     validation_batch_size=None,\n                    #     validation_freq=1,\n                    #     max_queue_size=10,\n                    #     workers=1,\n                    #     use_multiprocessing=False,\n                    )","metadata":{"execution":{"iopub.status.busy":"2022-07-03T10:42:53.826540Z","iopub.execute_input":"2022-07-03T10:42:53.826814Z","iopub.status.idle":"2022-07-03T13:11:22.974602Z","shell.execute_reply.started":"2022-07-03T10:42:53.826784Z","shell.execute_reply":"2022-07-03T13:11:22.973910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Plotting**","metadata":{}},{"cell_type":"code","source":"# summarize history for accuracy\nplt.plot(history5.history['binary_accuracy'])\nplt.plot(history5.history['val_binary_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:11:22.976411Z","iopub.execute_input":"2022-07-03T13:11:22.977196Z","iopub.status.idle":"2022-07-03T13:11:23.177477Z","shell.execute_reply.started":"2022-07-03T13:11:22.977157Z","shell.execute_reply":"2022-07-03T13:11:23.176711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Predict**","metadata":{}},{"cell_type":"code","source":"pred = model5.predict(val)\npred","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:11:23.178548Z","iopub.execute_input":"2022-07-03T13:11:23.178882Z","iopub.status.idle":"2022-07-03T13:12:21.862340Z","shell.execute_reply.started":"2022-07-03T13:11:23.178846Z","shell.execute_reply":"2022-07-03T13:12:21.861633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Converting Probabilities of Prediction**","metadata":{}},{"cell_type":"code","source":"# class map => { logit : class name }\nclass_map = { v: k for k, v in val.class_indices.items() }\n\n# apply a sigmoid because our model returns logits\npredict = tf.nn.sigmoid(pred)\npredict = tf.where(pred < 0.5, 0, 1).numpy()\n\npredict","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:12:21.864603Z","iopub.execute_input":"2022-07-03T13:12:21.865161Z","iopub.status.idle":"2022-07-03T13:12:21.879926Z","shell.execute_reply.started":"2022-07-03T13:12:21.865123Z","shell.execute_reply":"2022-07-03T13:12:21.879196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_df['targets']=[0 if x=='cat' else 1 for x in val_df['targets']]\nval_df['predict']=predict\nval_df","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:12:21.881187Z","iopub.execute_input":"2022-07-03T13:12:21.881470Z","iopub.status.idle":"2022-07-03T13:12:21.900522Z","shell.execute_reply.started":"2022-07-03T13:12:21.881436Z","shell.execute_reply":"2022-07-03T13:12:21.899876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Confusion Matrix**","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix, classification_report \nfig, ax = plt.subplots(figsize = (9, 6))\n\ncm = confusion_matrix(val_df[\"targets\"],val_df[\"predict\"])\n\ndisp = ConfusionMatrixDisplay(confusion_matrix = cm, display_labels = [\"cat\", \"dog\"])\ndisp.plot(cmap = plt.cm.Blues, ax = ax)\nax.set_title(\"Validation Set\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:12:21.901744Z","iopub.execute_input":"2022-07-03T13:12:21.902151Z","iopub.status.idle":"2022-07-03T13:12:22.112853Z","shell.execute_reply.started":"2022-07-03T13:12:21.902116Z","shell.execute_reply":"2022-07-03T13:12:22.112168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **MisClassified**","metadata":{}},{"cell_type":"code","source":"error_df=[row['PATH'] for i,row in val_df.iterrows() if row[\"targets\"] != row['predict']]\nerror_df[:10]","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:12:22.113876Z","iopub.execute_input":"2022-07-03T13:12:22.114126Z","iopub.status.idle":"2022-07-03T13:12:22.364148Z","shell.execute_reply.started":"2022-07-03T13:12:22.114091Z","shell.execute_reply":"2022-07-03T13:12:22.363330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import load_img\n\ndef show_error(nrow,ncol):    # This function creates a grid of images from  dataset.\n    \n    # Gallery using Matplotlib \n    fig, ax = plt.subplots(nrow,ncol,figsize = (12,12), dpi = 100)\n    axes = ax.ravel()\n    \n    for idx,ax  in enumerate(axes):\n        ax.imshow(load_img(error_df[idx]))\n    return fig.show()\n\nshow_error(5,5)","metadata":{"execution":{"iopub.status.busy":"2022-07-03T15:58:49.750275Z","iopub.execute_input":"2022-07-03T15:58:49.750562Z","iopub.status.idle":"2022-07-03T15:58:53.200631Z","shell.execute_reply.started":"2022-07-03T15:58:49.750530Z","shell.execute_reply":"2022-07-03T15:58:53.198961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Test Data-For Submission**","metadata":{}},{"cell_type":"code","source":"test_dir = \"../input/dogs-vs-cats/test1.zip\"\n\nimport zipfile\nwith zipfile.ZipFile(test_dir, \"r\") as tst:\n    tst.extractall('.')","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:14:45.562485Z","iopub.execute_input":"2022-07-03T13:14:45.562748Z","iopub.status.idle":"2022-07-03T13:14:51.923346Z","shell.execute_reply.started":"2022-07-03T13:14:45.562721Z","shell.execute_reply":"2022-07-03T13:14:51.922597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# File Path\nIMAGE_FOLDER_PATH = \"../working/test1\"\nFILE_PATH = [os.path.join(IMAGE_FOLDER_PATH,i) for i in os.listdir(IMAGE_FOLDER_PATH)]\n\n# Labels\nlabels=[i for i in os.listdir(IMAGE_FOLDER_PATH)]\n\n# Dataframe\ntest_df = pd.DataFrame({'PATH':FILE_PATH}) \ntest_df","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:20:37.262098Z","iopub.execute_input":"2022-07-03T13:20:37.262527Z","iopub.status.idle":"2022-07-03T13:20:37.308583Z","shell.execute_reply.started":"2022-07-03T13:20:37.262491Z","shell.execute_reply":"2022-07-03T13:20:37.307535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Processing Test Data**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator(\n#     featurewise_center=True,\n#     samplewise_center=True,\n#     featurewise_std_normalization=False,\n#     samplewise_std_normalization=False,\n#     zca_whitening=True,\n#     zca_epsilon=1e-06,\n#     rotation_range=90,\n#     width_shift_range=0.5,\n#     height_shift_range=0.5,\n#     brightness_range=None,\n#     shear_range=0.0,\n    zoom_range=0.5,\n#     channel_shift_range=0.0,\n#     fill_mode='nearest',\n#     cval=0.0,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rescale=1./255,\n#     preprocessing_function=None,\n#     data_format=None,\n#     validation_split=0.0,\n#     interpolation_order=1,\n#     dtype=None\n)\n\ntest=datagen.flow_from_dataframe(dataframe=test_df,\n                                     x_col=\"PATH\",\n                                     y_col=None,\n                                      class_mode=None,\n                                     shuffle=False,\n                                     target_size=(224, 224),\n                                     )\n\ntest","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:20:47.438403Z","iopub.execute_input":"2022-07-03T13:20:47.438662Z","iopub.status.idle":"2022-07-03T13:20:47.543064Z","shell.execute_reply.started":"2022-07-03T13:20:47.438633Z","shell.execute_reply":"2022-07-03T13:20:47.542301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"idx=[int(str(x).split('.')[0]) for x in labels]\nidx[:5]","metadata":{"execution":{"iopub.status.busy":"2022-07-03T13:21:20.643135Z","iopub.execute_input":"2022-07-03T13:21:20.643381Z","iopub.status.idle":"2022-07-03T13:21:20.656266Z","shell.execute_reply.started":"2022-07-03T13:21:20.643355Z","shell.execute_reply":"2022-07-03T13:21:20.655530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\npred=model5.predict(test) \nclasses=np.argmax(pred,axis=1)\nlen(classes)","metadata":{"execution":{"iopub.status.busy":"2022-07-03T14:08:50.342768Z","iopub.execute_input":"2022-07-03T14:08:50.343336Z","iopub.status.idle":"2022-07-03T14:11:16.273737Z","shell.execute_reply.started":"2022-07-03T14:08:50.343298Z","shell.execute_reply":"2022-07-03T14:11:16.272930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Final Submission**","metadata":{}},{"cell_type":"code","source":"submission=pd.DataFrame({'id': idx,\n                         'label': classes,\n                        })\n# submission\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-03T14:12:10.042691Z","iopub.execute_input":"2022-07-03T14:12:10.042958Z","iopub.status.idle":"2022-07-03T14:12:10.072371Z","shell.execute_reply.started":"2022-07-03T14:12:10.042927Z","shell.execute_reply":"2022-07-03T14:12:10.071714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Suggestions:-\n* Kaggle - https://www.kaggle.com/pythonkumar\n* GitHub - https://github.com/KumarPython​\n* Twitter - https://twitter.com/KumarPython\n* LinkedIn - https://www.linkedin.com/in/kumarpython/","metadata":{}}]}