{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Classifier to Distinguish Dogs and Cats Images","execution_count":null},{"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\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 5GB 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","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Importing Libraries","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#Importing Libraries\nimport numpy as np\nimport pandas as pd\nimport pickle\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.models import Sequential,Model\nfrom keras.layers import Conv2D,MaxPooling2D,Dropout,Flatten,Dense,GlobalMaxPooling2D,BatchNormalization\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator,load_img\nfrom tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras.applications.inception_v3 import InceptionV3\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nimport os\nimport random\nimport zipfile\n%matplotlib inline\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot')\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score,confusion_matrix,accuracy_score,precision_score,recall_score\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preparing Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Change the working directory\nos.chdir('/kaggle/working/')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Extracting Files\ntrain = \"../input/dogs-vs-cats/train.zip\"\ntest = \"../input/dogs-vs-cats/test1.zip\"\nwith zipfile.ZipFile(train,'r') as z:\n    z.extractall('.')\nwith zipfile.ZipFile(test, 'r') as z:\n    z.extractall('.')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Making a DataFrame\nfilename = os.listdir(\"/kaggle/working/train\")\ncategories = []\nfor name in filename:\n    category = name.split(\".\")[0]\n    if(category=='cat'):\n        categories.append(0)\n    else:\n        categories.append(1)\n\ndata = pd.DataFrame({\n    'filename':filename,\n    'category':categories\n})\n        \nprint(data.head())       ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Classification Model (Inception V3)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Inception Model (Pre-Trained)\nlocal_weights_file = \"../input/inceptionv3/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5\"\npre_trained_model = InceptionV3(input_shape=(150,150,3),include_top=False,weights=None)\npre_trained_model.load_weights(local_weights_file)\nfor layer in pre_trained_model.layers:\n  layer.trainable=False\npre_trained_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"last_layer = pre_trained_model.get_layer('mixed7')\nlast_output = last_layer.output\nx = GlobalMaxPooling2D()(last_output)\nx = Dense(1024,activation='relu')(x)\nx = BatchNormalization()(x)\nx = Dropout(0.5)(x)\nx = Dense(1,activation='sigmoid')(x) \n\nmodel = Model(pre_trained_model.input,x)\nmodel.compile(optimizer = RMSprop(lr=0.0001), loss = 'binary_crossentropy', metrics = ['acc'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Split into train and validation data\ndata['category'] = data['category'].replace({0:'cat',1:'dog'})\ntrain_data,val_data = train_test_split(data,test_size=0.1,random_state=1)\ntrain_data = train_data.reset_index(drop=True)\nval_data = val_data.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image Generator","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Generator\ntrain_datagen = ImageDataGenerator(rescale=1./255,\n                                   rotation_range=40,\n                                   width_shift_range=0.2,\n                                   height_shift_range=0.2,\n                                   shear_range=0.2,\n                                   zoom_range=0.2,\n                                   horizontal_flip=True,\n                                   fill_mode='nearest')\ntrain_generator = train_datagen.flow_from_dataframe(train_data,\n                                                    directory= \"/kaggle/working/train/\",\n                                                    class_mode='binary',\n                                                    target_size=(150,150),\n                                                    x_col=\"filename\",\n                                                    y_col=\"category\",\n                                                    batch_size=32)\n\nval_datagen = ImageDataGenerator(rescale=1./255)\nval_generator = val_datagen.flow_from_dataframe(val_data,\n                                                directory= \"/kaggle/working/train/\",\n                                                class_mode='binary',\n                                                target_size=(150,150),\n                                                x_col=\"filename\",\n                                                y_col=\"category\",\n                                                batch_size=32)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Callbacks","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Callbacks\nearlystop = EarlyStopping(monitor='val_loss',patience=4,verbose=1)\nlearning_reduce = ReduceLROnPlateau(patience=2,monitor=\"val_acc\",verbose=1,min_lr=0.00001,factor=0.5)\ncallbacks = [earlystop,learning_reduce]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Fitting the Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Fitting the model\nhistory = model.fit(train_generator,\n                    validation_data = val_generator,\n                    steps_per_epoch = len(train_data)//32,\n                    validation_steps = len(val_data)//32,\n                    epochs=10,\n                    callbacks=callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Visualize Training\ndef plot_graphs(history, string):\n    plt.plot(history.history[string])\n    plt.plot(history.history[\"val_\"+string])\n    plt.xlabel(\"Epochs\")\n    plt.ylabel(string)\n    plt.legend([string,\"val_\"+string])\n    plt.show()\nplot_graphs(history,'acc')\nplot_graphs(history,'loss')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Save Model\nmodel.save_weights('binary_classifier.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Accuracy and Loss of Validation Data\nloss,accuracy = model.evaluate_generator(val_generator,steps=np.ceil(len(val_data)/32),verbose=1)\nprint(\"Validation Accuracy: \",accuracy)\nprint(\"Validation Loss: \",loss)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Confusion Matrix","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Getting Predicted Value\ny_val = val_data['category'].replace({'cat':0,'dog':1})\ny_pred = model.predict_generator(val_generator,steps=np.ceil(len(val_data)/32))\ny_final = y_pred.round().astype(int)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Confusion Matrix\nconfusion = confusion_matrix(y_val, y_final) \n\nsns.heatmap(confusion, annot=True,cmap=\"Blues\",fmt='.1f')\nplt.xlabel(\"Predicted Label\")\nplt.ylabel(\"True Label\")\nplt.title(\"Confusion Matrix\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Test Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Test Data\ntest_filename=os.listdir(\"/kaggle/working/test1\")\ntest_data = pd.DataFrame({'filename': test_filename})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Test Generator\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_datagen.flow_from_dataframe(test_data,\n                                                directory= \"/kaggle/working/test1/\",\n                                                class_mode=None,\n                                                target_size=(128,128),\n                                                x_col=\"filename\",\n                                                y_col=None,\n                                                batch_size=32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Predict\npredict= model.predict_generator(test_generator,steps=np.ceil(len(test_data)/32),verbose=1)\ntest_data['category'] = np.where(predict>0.5,1,0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predicted Images Result","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Visualize predicted resuls with images\nsample_test = test_data.sample(n=9).reset_index()\nsample_test.head()\nplt.figure(figsize=(12,12))\nfor index, row in sample_test.iterrows():\n    filename = row['filename']\n    category = row['category']\n    img = load_img(\"./test1/\"+filename, target_size=(150,150))\n    plt.subplot(3, 3, index+1)\n    plt.imshow(img)\n    plt.xlabel(filename + '(' + \"{}\".format(category) + ')')\nplt.tight_layout()\nplt.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":4}