{"cells":[{"metadata":{},"cell_type":"markdown","source":"**This Kernel is an iplementation of CNN Architectures using VGG16 and VGG19 CNN architectures**\n\nThe Kernel Architeture is described as:\n<img src=\"https://qphs.fs.quoracdn.net/main-qimg-83c7dee9e8b039c3ca27c8dd91cacbb4\" width=\"900px\">\n\n\n**Important Features of VGG16 architectures**\n\n**Last Layer should have 1000 FC**"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**I have used Python's Keras library to implement the model. The following code shows the implementation of the Model**"},{"metadata":{},"cell_type":"markdown","source":"**There are two ways to build Keras models: sequential and functional. **\n\nThe sequential API allows you to create models layer-by-layer for most problems. It is limited in that it does not allow you to create models that share layers or have multiple inputs or outputs.\n\nAlternatively, the functional API allows you to create models that have a lot more flexibility as you can easily define models where layers connect to more than just the previous and next layers. In fact, you can connect layers to (literally) any other layer. As a result, creating complex networks such as siamese networks and residual networks become possible.\n"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# Imports\nfrom keras.layers import Input, Conv2D, MaxPool2D\nfrom keras.layers import Dense, Flatten\nfrom keras.models import Model\n\n# Define the input\n#   Unlike the Sequential model, you must create and define \n#   a standalone \"Input\" layer that specifies the shape of input \n#   data. The input layer takes a \"shape\" argument, which is a \n#   tuple that indicates the dimensionality of the input data.\n#   When input data is one-dimensional, such as the MLP, the shape \n#   must explicitly leave room for the shape of the mini-batch size \n#   used when splitting the data when training the network. Hence, \n#   the shape tuple is always defined with a hanging last dimension.\n\n_input = Input((224,224,1))\n\nconv1 = Conv2D(filters=64, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(_input)\nconv2 = Conv2D(filters=64, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv1)\npool1 = MaxPool2D((2,2))(conv2)\n\n\nconv3 = Conv2D(filters=128, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(pool1)\nconv4 = Conv2D(filters=128, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv3)\npool2 = MaxPool2D((2,2))(conv4)\n\n\nconv5 = Conv2D(filters=256, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(pool2)\nconv6 = Conv2D(filters=256, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv5)\nconv7 = Conv2D(filters=256, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv6)\npool3 = MaxPool2D((2,2))(conv7)\n\n\nconv8 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(pool3)\nconv9 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv8)\nconv10 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv9)\npool4 = MaxPool2D((2,2))(conv10)\n\n\nconv11 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(pool4)\nconv12 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv11)\nconv13 = Conv2D(filters=512, kernel_size=(3,3), padding = \"same\", activation=\"relu\")(conv12)\npool5 = MaxPool2D((2,2))(conv13)\n\nflat = Flatten()(pool5)\n\n\ndense1 = Dense(4096, activation=\"relu\")(flat)\ndense2 = Dense(4096, activation=\"relu\")(dense1)\noutput = Dense(1000, activation=\"softmax\")(dense2)\n\nvgg16_model = Model(inputs = _input, outputs= output)\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Using Pretrained Model of VGG16**\n\nKeras Library provides VGG16 pretrained model so that one can save time and use them for different usages:\n1. Transfer Learning\n2. Features extraction from Images\n3. Object Detection\n\nWe can add weights to respective layers after loading the model\n\n\n**What is a Pre-trained Model?**\n\nA pre-trained model has been previously trained on a dataset and contains the weights and biases that represent the features of whichever dataset it was trained on. Learned features are often transferable to different data. For example, a model trained on a large dataset of bird images will contain learned features like edges or horizontal lines that you would be transferable your dataset.\n\n**Why use a Pre-trained Model?**\n\nPre-trained models are beneficial to us for many reasons. By using a pre-trained model you are saving time. Someone else has already spent the time and compute resources to learn a lot of features and your model will likely benefit from it."},{"metadata":{},"cell_type":"markdown","source":"Keras works with batches of images. So, the first dimension is used for the number of samples (or images) you have.\n\nWhen you load a single image, you get the shape of one image, which is (size1,size2,channels).\n\nIn order to create a batch of images, you need an additional dimension: (samples, size1,size2,channels)\n\nThe preprocess_input function is meant to adequate your image to the format the model requires.\n\nSome models use images with values ranging from 0 to 1. Others from -1 to +1. Others use the \"caffe\" style, that is not normalized, but is centered.\n\nYou don't need to worry about the internal details of preprocess_input. But ideally, you should load images with the keras functions for that (so you guarantee that the images you load are compatible with preprocess_input).\n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.vgg16 import decode_predictions, preprocess_input\nfrom keras.preprocessing import image\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport seaborn as sns\n\n\n# loadingImages\ncatImage1 = \"../input/dogs-vs-cats-redux-kernels-edition/train/cat.10032.jpg\"\ndogImage1 = \"../input/dogs-vs-cats-redux-kernels-edition/train/dog.10042.jpg\"\nflowerImage1 = \"../input/flowers-recognition/flowers/flowers/rose/16078501836_3ac067e18a.jpg\"\nfruit1 = \"../input/fruits/fruits-360_dataset/fruits-360/Training/Mango/49_100.jpg\"\n\nimages = [catImage1, dogImage1, flowerImage1, fruit1]\n\ndef loadImage(path):\n    # changing dimensions to (224,224)     \n    img = image.load_img(path, target_size=(224,224))\n    # converting image to array\n    img = image.img_to_array(img)\n    # Expand the shape of an array.\n    img = np.expand_dims(img, axis=0)\n    img = preprocess_input(img)\n    return img\n\n\n\ndef getPredictions(model):\n    f,ax = plt.subplots(1,4)\n    f.set_size_inches(80, 40)\n    for i in range(4):\n        ax[i].imshow(Image.open(images[i]).resize((200,200), Image.ANTIALIAS))\n    plt.show()\n    \n    f,axes = plt.subplots(1,4)\n    f.set_size_inches(80, 20)\n    for i,img_path in enumerate(images):\n        img = loadImage(img_path)\n        preds = decode_predictions(model.predict(img), top=3)[0]\n        b = sns.barplot(y = [c[1] for c in preds], x = [c[2] for c in preds], color=\"gray\", ax= axes[i])\n        b.tick_params(labelsize=55)\n        f.tight_layout()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.vgg16 import VGG16\nvgg16_weights = '../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels.h5'\nvgg16_model = VGG16(weights=vgg16_weights)\ngetPredictions(vgg16_model)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**VGG19**\n\n![](https://cdn-images-1.medium.com/max/1600/1*cufAO77aeSWdShs3ba5ndg.jpeg)\n"},{"metadata":{},"cell_type":"markdown","source":"VGG19 is a similar model architecure as VGG16 with three additional convolutional layers, it consists of a total of 16 Convolution layers and 3 dense layers also stride 1."},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import VGG19\nvgg19_weights = '../input/vgg19/vgg19_weights_tf_dim_ordering_tf_kernels.h5'\nvgg19_model = VGG19(weights = vgg19_weights)\ngetPredictions(vgg19_model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}