{"cells":[{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"0.\"></a>\n# Content\n\n* [1. Summary](#1.)\n* [2. Cats and Dogs Dataset](#2.)\n* * [2.1. Randomly Visualization of Samples in the Dataset](#2.1.)\n* * [2.2. Some Evaluations About the Dataset](#2.2.)\n* [3. Convolutional Neural Network(CNN)](#3.)\n* * [3.1. Implementing CNN Architecture with Keras](#3.1.)\n* [4.Transfer Learning 1: Feature Extractor](#4.)"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\n\nfrom keras import layers\nfrom keras import models\nfrom keras import optimizers\nfrom keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator\nfrom keras import applications\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn import metrics\n\nimport glob\nimport os\nprint(\"Cats&Dogs Dataset Folder Contain:\",os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"1.\"></a>1. Summary\n\nIn this study, CNN architecture and transfer learning techniques will be used to classify cats and dogs in the Cats & Dogs dataset. Firstly, the dataset will be visualized and evaluated. Then, a CNN architecture will be created with keras, and trained and estimated on training and test sets respectively.  Then transfer learning technques will be applied on the dataset. \n\nTransfer learning is one of the important advantages of deep learning. There are two different transfer learning types used on image data; feature extractor and fine tunning. In this kernel transfer learning used as feature extractor on the Cats & Dogs dataset.\n\nIn this study you will learn:\n\n* Visualization of images in form of gallery\n* Use of CNN architecture in image classification.\n* Transfer Learning Type 1-Feature Extractor : pretrained model used such as feature extractor.\n\nAccuracy performace of the approaches as follows:\n\n* Custom CNN accurcy rate is %80(+-2)\n* Transfer Learning Type 1-Feature Extractor accuracy rate is %95(+-1)"},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"2.\"></a>2. Cats and Dogs Dataset\n\nThe dataset provide 25000 cats and dogs images to classify. Samples of the dataset as in form image gallery can be seen in figures in the next section. "},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"2.1.\"></a>2.1. Randomly Visualization of Samples in the Dataset\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"import zipfile\n\n\nzip_files = ['test1', 'train']\n# Will unzip the files so that you can see them..\nfor zip_file in zip_files:\n    with zipfile.ZipFile(\"../input/{}.zip\".format(zip_file),\"r\") as z:\n        z.extractall(\".\")\n        print(\"{} unzipped\".format(zip_file))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir('../input'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"IMAGE_FOLDER_PATH=\"../working/train\"\nFILE_NAMES=os.listdir(IMAGE_FOLDER_PATH)\nWIDTH=150\nHEIGHT=150","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"targets=list()\nfull_paths=list()\nfor file_name in FILE_NAMES:\n    target=file_name.split(\".\")[0]\n    full_path=os.path.join(IMAGE_FOLDER_PATH, file_name)\n    full_paths.append(full_path)\n    targets.append(target)\n\ndataset=pd.DataFrame()\ndataset['image_path']=full_paths\ndataset['target']=targets","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"dataset.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"target_counts=dataset['target'].value_counts()\nprint(\"Number of dogs in the dataset:{}\".format(target_counts['dog']))\nprint(\"Number of cats in the dataset:{}\".format(target_counts['cat']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def get_side(img, side_type, side_size=5):\n    height, width, channel=img.shape\n    if side_type==\"horizontal\":\n        return np.ones((height,side_size,  channel), dtype=np.float32)*255\n        \n    return np.ones((side_size, width,  channel), dtype=np.float32)*255\n\ndef show_gallery(show=\"both\"):\n    n=100\n    counter=0\n    images=list()\n    vertical_images=[]\n    rng_state = np.random.get_state()\n    np.random.shuffle(full_paths)\n    np.random.set_state(rng_state)\n    np.random.shuffle(targets)\n    for path, target in zip(full_paths, targets):\n        if target!=show and show!=\"both\":\n            continue\n        counter=counter+1\n        if counter%100==0:\n            break\n        #Image loading from disk as JpegImageFile file format\n        img=load_img(path, target_size=(WIDTH,HEIGHT))\n        #Converting JpegImageFile to numpy array\n        img=img_to_array(img)\n        \n        hside=get_side(img, side_type=\"horizontal\")\n        images.append(img)\n        images.append(hside)\n\n        if counter%10==0:\n            himage=np.hstack((images))\n            vside=get_side(himage, side_type=\"vertical\")\n            vertical_images.append(himage)\n            vertical_images.append(vside)\n            \n            images=list()\n\n    gallery=np.vstack((vertical_images)) \n    plt.figure(figsize=(12,12))\n    plt.xticks([])\n    plt.yticks([])\n    title={\"both\":\"Dogs and Cats\",\n          \"cat\": \"Cats\",\n          \"dog\": \"Dogs\"}\n    plt.title(\"100 samples of {} of the dataset\".format(title[show]))\n    plt.imshow(gallery.astype(np.uint8))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_gallery(show=\"cat\")\nshow_gallery(show=\"dog\")\nshow_gallery(show=\"both\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"2.1.\"></a>2.2. Some Evaluations About the Dataset\nThere are  three image galleries in above figures. First one showing only images of cats, second one showing only images of dogs and third one shows images of cats and dogs.  When the images in galleries are examined, it is possible to make the following evaluations;\n\n\n\n* There are many different types of cats\n* There are many different types of dogs\n* Some cat (dog) breeds are very similar to some dog (cat) breeds.\n* The backgrounds in the images are very different and noisy.\n* The difference in exposure of cats and dogs in the images is quite high.\n\nThe above features have the effect of making image classification difficult. In addition, the difference in light that makes image classification difficult, is little to be ignored."},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\".\"></a>3. Convolutional Neural Network(CNN)\n\n"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def show_model_history(modelHistory, model_name):\n    history=pd.DataFrame()\n    history[\"Train Loss\"]=modelHistory.history['loss']\n    history[\"Validatin Loss\"]=modelHistory.history['val_loss']\n    history[\"Train Accuracy\"]=modelHistory.history['accuracy']\n    history[\"Validatin Accuracy\"]=modelHistory.history['val_accuracy']\n  \n    history.plot(figsize=(12,8))\n    plt.title(\" Convulutional Model {} Train and Validation Loss and Accuracy History\".format(model_name))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"3.1.\"></a>3.1. Implementing CNN Architecture with Keras"},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"model=models.Sequential()\nmodel.add(layers.Conv2D(32, (3,3), activation=\"relu\", input_shape=(WIDTH, HEIGHT, 3)))\nmodel.add(layers.Conv2D(32, (3,3), activation=\"relu\"))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Dropout(0.25))\n\nmodel.add(layers.Conv2D(64, (3,3), activation=\"relu\"))\nmodel.add(layers.Conv2D(64, (3,3), activation=\"relu\"))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.MaxPooling2D(2,2))\nmodel.add(layers.Dropout(0.25))\n\nmodel.add(layers.Conv2D(128, (3,3), activation=\"relu\"))\nmodel.add(layers.Conv2D(128, (3,3), activation=\"relu\"))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Dropout(0.25))\n\nmodel.add(layers.Conv2D(64, (3,3), activation=\"relu\"))\nmodel.add(layers.Conv2D(64, (3,3), activation=\"relu\"))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Dropout(0.25))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation=\"relu\"))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(1, activation=\"sigmoid\"))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss=\"binary_crossentropy\", \n             optimizer=optimizers.RMSprop(lr=1e-4),\n             metrics=[\"accuracy\"])\nprint(\"[INFO]: model compiled...\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_train, dataset_test=train_test_split(dataset,\n                                                 test_size=0.2,\n                                                 random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen=ImageDataGenerator(\nrotation_range=15,\nrescale=1./255,\nshear_range=0.1,\nzoom_range=0.2,\nhorizontal_flip=True,\nwidth_shift_range=0.1,\nheight_shift_range=0.1)\n\ntrain_datagenerator=train_datagen.flow_from_dataframe(dataframe=dataset_train,\n                                                     x_col=\"image_path\",\n                                                     y_col=\"target\",\n                                                     target_size=(WIDTH, HEIGHT),\n                                                     class_mode=\"binary\",\n                                                     batch_size=150)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen=ImageDataGenerator(rescale=1./255)\ntest_datagenerator=test_datagen.flow_from_dataframe(dataframe=dataset_test,\n                                                   x_col=\"image_path\",\n                                                   y_col=\"target\",\n                                                   target_size=(WIDTH, HEIGHT),\n                                                   class_mode=\"binary\",\n                                                   batch_size=150)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"modelHistory=model.fit_generator(train_datagenerator,\n                                epochs=50,\n                                validation_data=test_datagenerator,\n                                validation_steps=dataset_test.shape[0]//150,\n                                steps_per_epoch=dataset_train.shape[0]//150\n                                )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Train Accuracy:{:.3f}\".format(modelHistory.history['accuracy'][-1]))\nprint(\"Test Accuracy:{:.3f}\".format(modelHistory.history['val_accuracy'][-1]))\nshow_model_history(modelHistory=modelHistory, model_name=\"\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"[Go to Content Menu](#0.)\n\n# <a class=\"anchor\" id=\"4.\"></a>4.Transfer Learning 1: Feature Extractor\n\nIn this section and in the next section, the use of  pretrained model on a dataset, on another dataset will be explained.\n\nIn traditional computer vision approaches, feature vectors are extracted from the images in the dataset, and these features are classified by supervised machine learning algorithms. In CNN deep learning approaches, images are given to the CNN model, which makes classification without feature extraction process. \n\nThe only advantage of deep learning is not to make classification without using feature extractor. CNN also allows for the use of pretrained models on new datasets. This approach is called Transfer Learning. There are two different Transfer Learning approaches;\n\n* Feature Extractor\n* Fine Tunning\n\nTransfer learning is based on the paradigm where a model previously trained on the A dataset can be used as a starting point on the B dataset. For example, a model that is trained for classification on snake and frog dataset can be used as a starting point for the classification of bear, panda and deer dataset. This can be thought of as how to find models that have been previously trained on the appropriate dataset. The models of the CNN architectures, which are featured in the image classification, are trained on \"ImageNet\" and are available in the keras library. These architectures can be easily used for the purpose of transfer learning on new datasets."},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"model=applications.VGG16(weights=\"imagenet\", include_top=False, input_shape=(WIDTH, HEIGHT, 3))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Since the last layer (4,4,512) is in dimensions, the length of the feature vector will be 4x4x512 = 8192."},{"metadata":{"trusted":true},"cell_type":"code","source":"counter=0\nfeatures=list()\nfor path, target in zip(full_paths, targets):\n    img=load_img(path, target_size=(WIDTH, HEIGHT))\n    img=img_to_array(img)\n    img=np.expand_dims(img, axis=0)\n    feature=model.predict(img)\n    features.append(feature)\n    counter+=1\n    if counter%2500==0:\n        print(\"[INFO]:{} images loaded\".format(counter))\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"features=np.array(features)\nprint(\"Before reshape,features.shape:\",features.shape)\nfeatures=features.reshape(features.shape[0], 4*4*512)\nprint(\"After reshape, features.shape:\",features.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"le=LabelEncoder()\ntargets=le.fit_transform(targets)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"features.shape:\",features.shape)\nprint(\"targets.shape:\",targets.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train, X_test, y_train, y_test=train_test_split(features, targets, test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import cross_val_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"clf=LogisticRegression(solver=\"lbfgs\")\nprint(\"{} training...\".format(clf.__class__.__name__))\nclf.fit(X_train, y_train)\ny_pred=clf.predict(X_test)\nprint(\"The model trained and used to predict the test data...\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Accuracy:\",metrics.accuracy_score(y_test, y_pred))\nprint(\"Confusion Matrix:\\n\",metrics.confusion_matrix(y_test, y_pred))\nprint(\"Classification Report:\\n\",metrics.classification_report(y_test, y_pred, target_names=[\"cat\", \"dog\"]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Notice here that we are able to reach 94% classification accuracy! This number is a massive improvement from our previous best of 80% in our custom CNN model. \n\nLet's find cross validated score for more trusted model. "},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"cv_scores=cross_val_score(LogisticRegression(solver=\"lbfgs\"), features, targets, cv=3 )\nprint(\"Cross validation scores obtained...\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Cross validated scores:{}\".format(cv_scores))\nprint(\"Mean of cross validated scores:{:.3f}\".format(cv_scores.mean()))","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":4}