{"cells":[{"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\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_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# importing the modulus\nfrom keras.preprocessing.image import ImageDataGenerator,img_to_array,load_img\nfrom keras.models import Sequential\nfrom keras.layers import Dropout, Flatten, Dense  , Activation\nfrom keras import applications\nimport re","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6421363bc3fe2dc3fa78d3305912360471936beb"},"cell_type":"markdown","source":"Visualizing a image of both cat and dog"},{"metadata":{"trusted":true,"_uuid":"50eb9f8d164538f261d83f7d7a86cb42f0802d2e"},"cell_type":"code","source":"import matplotlib.pyplot as plt\nfig,axes=plt.subplots(nrows=1,ncols=2)\n\nimg1=load_img('../input/dogs-vs-cats-redux-kernels-edition/train/dog.1.jpg',target_size=(150,150))\naxes[0].imshow(img1)\naxes[0].set_title(\"Cat\")\nimg2=load_img('../input/dogs-vs-cats-redux-kernels-edition/train/cat.1.jpg',target_size=(150,150))\naxes[1].imshow(img2)\naxes[1].set_title(\"Dog\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3a89aabaf826cd2ef19cec1521f17fbb7344f9c4"},"cell_type":"code","source":"# Setting the parameters \nimg_width = 150\nimg_height = 150\nTRAIN_DIR = '../input/dogs-vs-cats-redux-kernels-edition/train/'\nTEST_DIR = '../input/dogs-vs-cats-redux-kernels-edition/test/'\ntrain_images_dogs_cats = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] # use this for full dataset\ntest_images_dogs_cats = [TEST_DIR+i for i in os.listdir(TEST_DIR)] ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3f81b1de2d20dc3673fe9c653cf7d46055f7fec1"},"cell_type":"code","source":"# images in directory path\ntrain_images_dogs_cats[:5]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dd646e6fa6794c69512bc279e7250fb537eae8ed"},"cell_type":"markdown","source":"### Sorting the images in their directory by number in image name.\nHelper function for natural Sorting the images of dog and cat in their directory.                                                                                             \nIn a classical alphanumerical sort we will have something like : 1 10 11 12 2 20 21 3 4 5 6 7                                                                           \nIf you're using Natural ordering, it will be :1 2 3 4 5 6 7 10 11 12 20 21"},{"metadata":{"trusted":true,"_uuid":"833264128c8a001c30193118b4ca274c0907fb87"},"cell_type":"code","source":"def atoi(text):\n    return int(text) if text.isdigit() else text\n\ndef natural_keys(text):\n    return [ atoi(c) for c in re.split('(\\d+)', text) ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9a3f658576e92959d55a92742f533dc3b0d85a96"},"cell_type":"code","source":"#Natural sorting on training data\ntrain_images_dogs_cats.sort(key=natural_keys)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c4f20fd3e94cff5bfe3764179bc54858084672d2"},"cell_type":"code","source":"# After sorting directory\ntrain_images_dogs_cats[:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"934eb8bb9bd15afb21ba9100d1800b2873ef5eaa"},"cell_type":"code","source":"# dog images starts from index 12500\ntrain_images_dogs_cats[12500:12505]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8e00d68d553eebb3514612503fc97f3a167b8dab"},"cell_type":"markdown","source":"## Chosing a subset of training images.\nThe dataset consist of 25000 images of both cat and dog i.e 12500 images of each dog and cat.                                                               \nWe will be using 3000 images of  cat and dog each . A total of which is 6000 images combined dog and cat.                                         \nCat images ranges from index 0 to 12499 and dog images ranges from index 12500 to 25499\nSo, selecting first 3000 images which are cat .\nDog images start from index 12500 and goes to 15500 for 3000 images of dog."},{"metadata":{"trusted":true,"_uuid":"6caaf150addab32e174e5c9d522698bdb340903e"},"cell_type":"code","source":"train_images_dogs_cats = train_images_dogs_cats[0:3000] + train_images_dogs_cats[12500:15500] ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9d3c73ae20bbad609ae4d906f1b5eac4f5595388"},"cell_type":"code","source":"# natural sorting the test images\ntest_images_dogs_cats.sort(key=natural_keys)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3f9e08c1f0c96c880a03923ad318347fc750c24b"},"cell_type":"markdown","source":"**Data Preprocessing** converting images to array"},{"metadata":{"trusted":true,"_uuid":"849552c65a9c7c172c5f3fbd2a6c1f13f6f2f949"},"cell_type":"code","source":"def prepare_data(list_of_images):\n    \"\"\"\n    Returns a array of images\n    \n    \"\"\"\n    x = [] # images as arrays\n    for image in list_of_images:\n        x.append(img_to_array(load_img(image,target_size=(img_width,img_height))))\n    return x","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c1dbeca69f0481c57ceb079648bec00f3f37f30d"},"cell_type":"markdown","source":"Preparing data and generating their labels"},{"metadata":{"trusted":true,"_uuid":"980b1ce0c557c336e8880a2d414879523cb84154"},"cell_type":"code","source":"X=prepare_data(train_images_dogs_cats)\nX=np.array(X)\ny=np.array([0]*3000 + [1]*3000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"05a9bb63b934933393fb7dcbae4e430763cedecf"},"cell_type":"code","source":"# Spliting the data in training and validation data\nfrom sklearn.model_selection import train_test_split\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=1) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b37ba1b69a2646921dab3019e3157bf953218bbd"},"cell_type":"code","source":"# Shape of training data\nprint('Shape of training data {}'.format(X_train.shape))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"12076da5cbc90580d8fe0090848a2f823a815bf5"},"cell_type":"code","source":"nb_train=len(X_train)\nnb_validation=len(X_val)\nbatch_size=16","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6b12bbdf8f8c07950128c390c7829c9d1869449c"},"cell_type":"markdown","source":"# Using the bottleneck features of a pre-trained network                                                                                                                       \nA more refined approach would be to leverage a network pre-trained on a large dataset. Such a network would have already learned features that are useful for most computer vision problems, and leveraging such features would allow us to reach a better accuracy than any method that would only rely on the available data.\n\nWe will use the VGG16 architecture, pre-trained on the ImageNet dataset --a model previously featured on this blog. Because the ImageNet dataset contains several \"cat\" classes (persian cat, siamese cat...) and many \"dog\" classes among its total of 1000 classes, this model will already have learned features that are relevant to our classification problem. In fact, it is possible that merely recording the softmax predictions of the model over our data rather than the bottleneck features would be enough to solve our dogs vs. cats classification problem extremely well. However, the method we present here is more likely to generalize well to a broader range of problems, including problems featuring classes absent from ImageNet.\n\nOur strategy will be as follow: we will only instantiate the convolutional part of the model, everything up to the fully-connected layers. We will then run this model on our training and validation data once, recording the output (the \"bottleneck features\" from th VGG16 model: the last activation maps before the fully-connected layers) in two numpy arrays. Then we will train a small fully-connected model on top of the stored features.                                                                                                                                                    Check VGG16 model here **\n[https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3](http://)"},{"metadata":{"trusted":true,"_uuid":"fbe509a0480ab74a71246240685c29a87f56855e"},"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1. / 255)\n\n# build the VGG16 network\nmodel_vgg16 = applications.VGG16(include_top=False, weights='../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')\n    \n# creating a train generator \ngenerator = datagen.flow(X_train,y_train, batch_size=batch_size,shuffle=False)\n    \n# getting training data bottle neck features from  VGG16 model\nbottleneck_features_train = model_vgg16.predict_generator(generator, nb_train // batch_size ,verbose=1 ) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"99dccc72586762de22da644e121d12d0489a119a"},"cell_type":"code","source":"# validation generator\ngenerator = datagen.flow(X_val,y_val,batch_size=batch_size,shuffle=False)\n    \n# getting validation data bottle neck features from VGG16 model\nbottleneck_features_validation = model_vgg16.predict_generator(\n        generator, nb_validation // batch_size , verbose =1 ) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a97f36e38e6ea3c1dd0ac0dfae7269b12a9a0367"},"cell_type":"code","source":"# shape of bottleneck features\nprint(\"Shape of training bottleneck feature {}\".format(bottleneck_features_train.shape))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ae6189a9218b0f587982c7027f35d96ee6775209"},"cell_type":"markdown","source":"# Building the top model"},{"metadata":{"trusted":true,"_uuid":"b1511ba08116aaa0d77877b7fdfa0c56e45f3329"},"cell_type":"code","source":"model = Sequential()\n#input layer\nmodel.add(Flatten(input_shape=bottleneck_features_train.shape[1:]))\n\n# first hidden layer\nmodel.add(Dense(units=256,activation='relu'))\nmodel.add(Dropout(0.4))\n\n# Second hidden layer\nmodel.add(Dense(units=126,activation='relu'))\nmodel.add(Dropout(0.4))\n\n#output layer\nmodel.add(Dense(1, activation='sigmoid'))\nmodel.compile(optimizer='rmsprop',\n                  loss='binary_crossentropy', metrics=['accuracy'])\n\n#fitting the model\nhistory=model.fit(x=bottleneck_features_train,y=y_train,\n                  epochs=10,\n                  batch_size=batch_size,\n                  validation_data=(bottleneck_features_validation,y_val))\n\nmodel.save('TL_model.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6bc3a983498979f73e062e04f0555d1680b3234a"},"cell_type":"code","source":"# visualizing the model\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nplt.plot(history.history['acc'],label='Train_acc')\nplt.plot(history.history['val_acc'],label='val_acc')\nplt.xlabel('number of epochs')\nplt.ylabel('accuracy')\nplt.title('Model Accuracy Graph')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7b6161fb536d4167d69b29c7c861ecdcae4fae17"},"cell_type":"code","source":"# predicting result of test data\nX_test = prepare_data(test_images_dogs_cats)\nX_test=np.array(X_test)\nprint('Shape of test data {}'.format(X_test.shape))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a1386be51f57dd1c8ee0e49b8f7bc975539a8fdd"},"cell_type":"code","source":"nb_test=len(X_test)\nbatch_size=20","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f44254ad7860bdad5eed81d96af12828f9ef2159"},"cell_type":"markdown","source":"# Predicting the result of test data                                                                                                                                                            \n Here first we calculate the bottle neck features of our test data and give this features to input to top model to get the predictions."},{"metadata":{"trusted":true,"_uuid":"1a562aa950a93c20e2e9f828a9536fbe4e0a8df2"},"cell_type":"code","source":"# test data generator\ntest_datagen = ImageDataGenerator(rescale=1. / 255)\ntest_generator = test_datagen.flow( X_test, batch_size=batch_size,shuffle=False)\n\nmodel_vgg16 = applications.VGG16(include_top=False, weights='../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')\n\n#bottle neck features of our test data\nbottleneck_feature_test_data=model_vgg16.predict_generator(test_generator,nb_test//batch_size,verbose=1)\n\n# predicting probablities\nprediction_probabilities = model.predict(bottleneck_feature_test_data,verbose=1) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"482855db3f14f58dc3b92dc4f3813709b95cd946"},"cell_type":"code","source":"# Visualizing the result of prediction.\nfor i in range(10):\n    if prediction_probabilities[i][0] > 0.5:\n        print(\"I am {a:.2%} sure I am Dog\".format(a=prediction_probabilities[i][0]))\n    else:\n        print(\"I am {a:.2%} sure I am Cat\".format(a=(1-prediction_probabilities[i][0])))\n    plt.imshow(load_img(test_images_dogs_cats[i],target_size=(150,150)))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"290b52275624aef6fc55bf9cb666280a20211b3b"},"cell_type":"code","source":"# creating a submission file\ncounter = range(1, len(test_images_dogs_cats) +1 )\nsolution = pd.DataFrame({\"id\": counter, \"label\":list(prediction_probabilities)})\ncols = ['label']\n\nfor col in cols:\n    solution[col] = solution[col].map(lambda x: str(x).lstrip('[').rstrip(']')).astype(float)\n\nsolution.to_csv(\"dogsVScats.csv\", index = False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}