{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# imports\nimport os, cv2, itertools, re\nimport keras\nfrom keras.utils.np_utils import to_categorical\nfrom keras.datasets import mnist\nfrom keras.layers import Convolution2D, Dropout\nfrom keras.models import Sequential\nfrom keras import layers\nfrom keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D\nfrom keras.models import Model\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix\nimport random as rnd\nfrom keras import backend as K\nfrom keras.utils import np_utils\nfrom keras.callbacks import CSVLogger\nfrom keras.models import load_model\nfrom keras.utils import np_utils as npu\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.utils import shuffle\nimport sklearn\nfrom sklearn.model_selection import train_test_split\n\n# function to return the most frequent element in a list (for good/bad predictions)\ndef most_frequent(listt):\n    return max(set(listt), key = listt.count)\n\n# the mnist model\ndef mnist_model():\n    model = Sequential()\n\n    model.add(Convolution2D(32, (3, 3), padding='same', input_shape=(28, 28, 1)))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='same'))\n    model.add(Dropout(0.25))\n\n    model.add(Convolution2D(64, (3, 3), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='same'))\n    model.add(Dropout(0.25))\n\n    model.add(Flatten())\n\n    model.add(Dense(128))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(Dropout(0.25))\n\n    model.add(Dense(10))\n    model.add(Activation('softmax'))\n\n    return model\n\n# the cats vs dogs convolutional model\ndef animals_model():\n    model = Sequential()\n\n    model.add(Convolution2D(32, (3,3), padding='same', input_shape=(80, 80, 1)))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n\n    model.add(Convolution2D(64, (3,3), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(0.4))\n\n    model.add(Convolution2D(128, (3,3), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(0.4))\n\n    model.add(Convolution2D(256, (3,3), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(0.4))\n    \n    model.add(Convolution2D(512, (3,3), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(0.4))\n\n    model.add(Flatten())\n    \n    model.add(Dropout(0.4))\n\n    model.add(Dense(120))\n    model.add(Activation('relu'))\n    \n    model.add(Dense(2))\n    model.add(Activation('softmax'))\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# setting the batch size for each epoch, number of classes (2), number of epochs\nBATCH_SIZE = 64\nnum_classes = 2\nNUM_EPOCHS = 50\n\n# array of labels for plotting confusion matrix and badly classified images\nanimal_labels = [\"cat\", \"dog\"]\n\n# paths to the train and test data\nTRAIN_DIR = '../input/dogs-vs-cats-redux-kernels-edition/train/'\nTEST_DIR = '../input/dogs-vs-cats-redux-kernels-edition/test/'\n\n# data preparation\nX = []\ny = []\nconvert = lambda category : int(category == 'dog')\n# importing and processing training data\ndef create_test_data(path):\n    for p in os.listdir(path):\n        if(os.path.join(path,p) != '../input/dogs-vs-cats-redux-kernels-edition/train/train'):\n            category = p.split(\".\")[0]\n            category = convert(category)\n            # conversion to grayscale\n            img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE)\n            # resize all images to 80x80 pixels\n            new_img_array = cv2.resize(img_array, dsize=(80, 80))\n            X.append(new_img_array)\n            y.append(category)\n    \ncreate_test_data(TRAIN_DIR)\nX = np.array(X).reshape(-1, 80,80,1)\ny = np.array(y)\n\n# normalizing image data\nX = X/255.0\n\n# validation and training split\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=1)\n\n# importing the test data\nX_test = []\ndef create_test1_data(path):\n    for p in os.listdir(path):\n        if(os.path.join(path,p) != '../input/dogs-vs-cats-redux-kernels-edition/test/test'):\n            img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE)\n            new_img_array = cv2.resize(img_array, dsize=(80, 80))\n            X_test.append(new_img_array)\n\ncreate_test1_data(TEST_DIR)\nX_test = np.array(X_test).reshape(-1,80,80,1)\nX_test = X_test/255\n\n# one hot encoding of vector labels: 0 - cat, 1- dog\ny_train = to_categorical(y_train)\ny_val = to_categorical(y_val)\n\nprint(y_val.shape)\n\n# initializing conv model\nanimal_cnn = animals_model()\n\n# compiling model\nanimal_cnn.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n\n# imageDataGenerators for data augmentation\ntrain_datagen = ImageDataGenerator(\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True)\n\nval_datagen = ImageDataGenerator(\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True)\n\ntrain_generator = train_datagen.flow(X_train, y_train, batch_size=BATCH_SIZE)\nvalidation_generator = val_datagen.flow(X_val, y_val, batch_size=BATCH_SIZE)\n\n# training the network\ntrain_history = animal_cnn.fit_generator(\n    train_generator, \n    steps_per_epoch=X_train.shape[0] // BATCH_SIZE,\n    epochs=NUM_EPOCHS,\n    validation_data=validation_generator,\n    verbose=0,\n    validation_steps=X_val.shape[0] // BATCH_SIZE\n)\n\n# saving the network\nanimal_cnn.save('dogs_cats_model.h5')\n\n# testing network performance\nscore = animal_cnn.evaluate(X_val, y_val, verbose=1)\nprint('Dogs vs Cats Evaluation Loss: ', score[0])\nprint('Dogs vs Cats Evaluation Accuracy: ', score[1])\n\n# Print Model Stats\nprint('Training accuracy')\nprint(max(train_history.history['accuracy']))\n\nprint('Validation accuracy')\nprint(max(train_history.history['val_accuracy']))\n\n# plotting training/validation accuracy/loss evolution\nplt.figure()\nplt.plot(train_history.history['accuracy'], color='C0', label='Training acc')\nplt.title('Dogs vs Cats CNN Training Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(loc='lower right')\nplt.show()\n\nplt.figure()\nplt.plot(train_history.history['loss'], color='C0', label='Training loss')\nplt.title('Dogs vs Cats CNN Training Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(loc='upper right')\nplt.show()\n\nplt.figure()\nplt.plot(train_history.history['val_accuracy'], color='C0', label='Validation acc')\nplt.title('Dogs vs Cats CNN Validation Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(loc='lower right')\nplt.show()\n\nplt.figure()\nplt.plot(train_history.history['val_loss'], color='C0', label='Validation loss')\nplt.title('Dogs vs Cats CNN Validation Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(loc='upper right')\nplt.show()\n\n# getting predictions for the test data for the confusion matrix\ny_pred = animal_cnn.predict(X_val)\ny_pred = np.argmax(y_pred,axis=1)\ny_true = np.asarray([np.argmax(i) for i in y_val])\nprint(y_pred.shape)\nprint(y_true.shape)\n\n# generating confusion matrix\ncm = confusion_matrix(y_true, y_pred)\nprint(cm)\ncm_norm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n# plotting confusion matrix\nsns.set(font_scale=1.5)\nfig, ax = plt.subplots(figsize=(10,10))\nax = sns.heatmap(\n    cm_norm, annot=True, linewidths=0, square=False, cmap='Greens',\n    yticklabels=animal_labels, xticklabels=animal_labels,\n    vmin=0, vmax=np.max(cm_norm), fmt='.2f',\n    annot_kws={'size': 20}\n)\nax.set(xlabel='Predicted Label', ylabel='Actual Label', title='Dogs vs Cats CNN Confusion Matrix')\nplt.show()\n\n# plotting predictions for the first 10 test images\nfor x in range(0, 10):\n    original_test_image = X_test[x].reshape(1,80, 80, 1)\n    prediction = animal_cnn.predict(original_test_image)\n    prediction_text = \"\"\n    pred_val = max(prediction[0])\n    if prediction[0][0] == pred_val:\n        prediction_text = \"cat\"\n    else:\n        prediction_text = \"dog\"\n    \n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(X_test[x, :, :, 0], cmap='gray')\n    title_text = \"Predicted: \" + prediction_text\n    pic_name = \"prediction\" + str(x) + \".jpg\"\n    plt.title(title_text, fontsize=20)\n    plt.savefig(pic_name)\n    plt.show()","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}