{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport glob\nimport zipfile\nimport seaborn as sb\nimport numpy as np # linear algebra\nimport pandas as pd # data processing \nfrom PIL import Image\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom tensorflow.keras.callbacks import EarlyStopping,ModelCheckpoint\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nfrom keras.models import Model,Sequential\nfrom keras.layers import Conv2D, GlobalAveragePooling2D, Dropout, Flatten, Dense, Activation,GlobalMaxPooling2D\nfrom tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input\nfrom sklearn.metrics import confusion_matrix,classification_report\nfrom keras.optimizers import Adam\n\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-09T12:01:19.998814Z","iopub.execute_input":"2021-11-09T12:01:19.999375Z","iopub.status.idle":"2021-11-09T12:01:20.015409Z","shell.execute_reply.started":"2021-11-09T12:01:19.999334Z","shell.execute_reply":"2021-11-09T12:01:20.013923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Unzip the files \nzip_file = glob.glob('/kaggle/input/dogs-vs-cats/*.zip')  #return any files with .zip extension\nfor file in zip_file:\n    #extract file into a temp folder\n    with zipfile.ZipFile(file,\"r\") as zip_ref:\n        zip_ref.extractall(\"datasets\")\n        ","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:01:22.930985Z","iopub.execute_input":"2021-11-09T12:01:22.931575Z","iopub.status.idle":"2021-11-09T12:01:48.355459Z","shell.execute_reply.started":"2021-11-09T12:01:22.931532Z","shell.execute_reply":"2021-11-09T12:01:48.354357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"  def prepare_data(dir_path):\n    filenames = os.listdir(dir_path)\n    labels = []\n    for filename in filenames:\n        label = filename.split('.')[0]\n        if label == 'dog':\n            labels.append(1)\n        else:\n            labels.append(0)\n    return filenames,labels\n\n#prepare data \ntrain_filenames,train_labels = prepare_data('datasets/train') \ntest_filenames,test_labels = prepare_data('datasets/test1') \n\ndf_train = pd.DataFrame({'filename':train_filenames,'class': train_labels})\ndf_test = pd.DataFrame({'filename': test_filenames,'class': test_labels})","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:07.776769Z","iopub.execute_input":"2021-11-09T12:02:07.777215Z","iopub.status.idle":"2021-11-09T12:02:07.852010Z","shell.execute_reply.started":"2021-11-09T12:02:07.777175Z","shell.execute_reply":"2021-11-09T12:02:07.850954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:12.439158Z","iopub.execute_input":"2021-11-09T12:02:12.439633Z","iopub.status.idle":"2021-11-09T12:02:12.451912Z","shell.execute_reply.started":"2021-11-09T12:02:12.439585Z","shell.execute_reply":"2021-11-09T12:02:12.450672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:15.374497Z","iopub.execute_input":"2021-11-09T12:02:15.374938Z","iopub.status.idle":"2021-11-09T12:02:15.389740Z","shell.execute_reply.started":"2021-11-09T12:02:15.374899Z","shell.execute_reply":"2021-11-09T12:02:15.388686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape, df_test.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:19.022960Z","iopub.execute_input":"2021-11-09T12:02:19.023402Z","iopub.status.idle":"2021-11-09T12:02:19.029898Z","shell.execute_reply.started":"2021-11-09T12:02:19.023356Z","shell.execute_reply":"2021-11-09T12:02:19.028788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sb.countplot(x='class',data=df_train).set_title(\"Data Distribution\")","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:21.645714Z","iopub.execute_input":"2021-11-09T12:02:21.646146Z","iopub.status.idle":"2021-11-09T12:02:21.780266Z","shell.execute_reply.started":"2021-11-09T12:02:21.646110Z","shell.execute_reply":"2021-11-09T12:02:21.779035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# we can see that our dataset is prettey balanced. we will try to reduce the samples\n# to 2000 for each class since we will use a pretrained model\ncats = df_train[df_train['class']==0][:3000]\ndogs = df_train[df_train['class']==1][:3000]\n#concat the two dataframes\ndf = pd.concat([cats,dogs])\n#shuffle\ndf = df.sample(frac=1)\ndf.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:39.873773Z","iopub.execute_input":"2021-11-09T12:02:39.874242Z","iopub.status.idle":"2021-11-09T12:02:39.890230Z","shell.execute_reply.started":"2021-11-09T12:02:39.874202Z","shell.execute_reply":"2021-11-09T12:02:39.889169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DIR_PATH = 'datasets/train/'\n#Let's show some image from the dataframe\nfig, axis = plt.subplots(3, 3, figsize=(20, 20))\nfor i, ax in enumerate(axis.flat):\n    img = load_img(DIR_PATH+df['filename'].iloc[i]) \n    ax.imshow(img)\n    ax.axis('off')","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:02:43.437374Z","iopub.execute_input":"2021-11-09T12:02:43.437841Z","iopub.status.idle":"2021-11-09T12:02:44.669373Z","shell.execute_reply.started":"2021-11-09T12:02:43.437793Z","shell.execute_reply":"2021-11-09T12:02:44.668100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#set some parameters \nimage_shape = (224,224)\nepochs = 5\nbatch_size = 32\n# to avoid type errors we cast df columns to string opjects\ndf['filename'] = df['filename'].astype('str')\ndf['class'] = df['class'].astype('str')\n#split data ibto train and validation set\ntrain, validation = train_test_split(df, test_size=0.2)\n#reset indexes \ntrain = train.reset_index()\nvalidation = validation.reset_index()\n\n#data augmenetation \ntrain_gen = ImageDataGenerator(\n    rotation_range=15,\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest',\n    width_shift_range=0.1,\n    height_shift_range=0.1)\n\n#train generator \ntrain_generator = train_gen.flow_from_dataframe(\n    train, \n    directory = DIR_PATH,\n    x_col='filename',\n    y_col=\"class\",\n    class_mode=\"categorical\",\n    target_size=image_shape,\n    batch_size=batch_size)\n#validation generator \nvalidation_gen = ImageDataGenerator(\n    rescale=1./255)\n\nval_generator = validation_gen.flow_from_dataframe(\n    validation,  \n    directory = DIR_PATH,\n    x_col='filename',\n    y_col=\"class\",\n    class_mode=\"categorical\",\n    target_size=image_shape,\n    batch_size=batch_size)","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:03:53.549123Z","iopub.execute_input":"2021-11-09T12:03:53.549602Z","iopub.status.idle":"2021-11-09T12:03:53.664728Z","shell.execute_reply.started":"2021-11-09T12:03:53.549565Z","shell.execute_reply":"2021-11-09T12:03:53.663763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_image= train.sample(n=1).reset_index(drop=True)\nsample_generator = train_gen.flow_from_dataframe(\n    sample_image,\n    directory = DIR_PATH,\n    x_col='filename',\n    y_col='class')\nplt.figure(figsize=(12, 12))\nfor i in range(0, 9):\n    plt.subplot(3, 3, i+1)\n    for X_batch, Y_batch in sample_generator:\n        image = X_batch[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:04:52.922607Z","iopub.execute_input":"2021-11-09T12:04:52.923275Z","iopub.status.idle":"2021-11-09T12:04:54.871179Z","shell.execute_reply.started":"2021-11-09T12:04:52.923220Z","shell.execute_reply":"2021-11-09T12:04:54.870117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#build the Resnet model \nresnet = ResNet50(weights='imagenet',\n                      input_shape= (224,224,3),\n                      include_top= False)  \n\n\n#show the base model summary \nresnet.summary()\n#show how manay layers in the Resnet Network\nlayers = resnet.layers\nprint(f'Number of Layers: {len(layers)} ')","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:10:50.891540Z","iopub.execute_input":"2021-11-09T12:10:50.892278Z","iopub.status.idle":"2021-11-09T12:10:53.557483Z","shell.execute_reply.started":"2021-11-09T12:10:50.892222Z","shell.execute_reply":"2021-11-09T12:10:53.556446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# number of samples for each set \nsize_train = train.shape[0]\nsize_val = validation.shape[0]\n# early stopping \ncallbacks = EarlyStopping(patience = 3, monitor='val_acc')\n                        \n# let's train our Model \ninputs = resnet.input\n# add an average pooling layer\nx = resnet.output\nx = GlobalAveragePooling2D()(x)\n#first dense layer\nx = Dense(512, activation='relu')(x)\n#dropout \nx = Dropout(0.5)(x)\n# output layer\noutputs = Dense(2, activation ='softmax')(x)\n# this is the model we will train\nmodel = Model(inputs=inputs, outputs=outputs)\n\n# freeze all convolutional Resnet layers\nfor layer in layers:\n    layer.trainable = False\n# compile the model \nmodel.compile(optimizer=Adam(lr=0.001),\n              loss='categorical_crossentropy',\n              metrics=['accuracy'])\n# train the model on the new data for a few epochs\nhistory = model.fit_generator(\n    train_generator,\n    epochs= epochs,\n    validation_data = val_generator,\n    validation_steps = size_val//batch_size,\n    steps_per_epoch = size_train//batch_size,\n    callbacks = [callbacks])","metadata":{"execution":{"iopub.status.busy":"2021-11-09T12:11:05.666821Z","iopub.execute_input":"2021-11-09T12:11:05.667160Z","iopub.status.idle":"2021-11-09T13:00:13.545524Z","shell.execute_reply.started":"2021-11-09T12:11:05.667131Z","shell.execute_reply":"2021-11-09T13:00:13.544334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot training loss vs validation loss\nsb.set_style('whitegrid')\nplt.figure()\nfig,(ax1, ax2)=plt.subplots(1,2,figsize=(19,8))\nax1.plot(history.history['loss'])\nax1.plot(history.history['val_loss'])\nax1.legend(['Training','Validation'])\nax1.set_title('Loss')\nax1.set_xlabel('#epochs')\n## plot training accuracy vs validation accuracy \nax2.plot(history.history['accuracy'])\nax2.plot(history.history['val_accuracy'])\nax2.legend(['Training','Validation'])\nax2.set_title('Acurracy')\nax2.set_xlabel('#epochs')","metadata":{"execution":{"iopub.status.busy":"2021-11-09T13:01:16.511828Z","iopub.execute_input":"2021-11-09T13:01:16.512369Z","iopub.status.idle":"2021-11-09T13:01:17.055882Z","shell.execute_reply.started":"2021-11-09T13:01:16.512316Z","shell.execute_reply":"2021-11-09T13:01:17.054771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Evaluate\nloss, acc = model.evaluate_generator(val_generator)\nprint(\"Validation Accuracy = %f \\nValidation Loss = %f \" % (acc, loss))","metadata":{"execution":{"iopub.status.busy":"2021-11-09T13:04:10.849944Z","iopub.execute_input":"2021-11-09T13:04:10.850407Z","iopub.status.idle":"2021-11-09T13:04:10.856817Z","shell.execute_reply.started":"2021-11-09T13:04:10.850361Z","shell.execute_reply":"2021-11-09T13:04:10.855516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#save the weights of the model to hdf5 file \nmodel.save_weights(\"resnet_model.h5\")\nprint(\"Model Saved.\")","metadata":{"execution":{"iopub.status.busy":"2021-11-09T13:06:50.729117Z","iopub.execute_input":"2021-11-09T13:06:50.729539Z","iopub.status.idle":"2021-11-09T13:06:51.112572Z","shell.execute_reply.started":"2021-11-09T13:06:50.729503Z","shell.execute_reply":"2021-11-09T13:06:51.111085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = validation['class'].astype('int32')\npredict =  model.predict_generator(val_generator)\npredictions = np.where(predict > 0.5, 1,0)\npredictions = np.argmax(predictions, axis=1)\n#show the confusion matrix \nconf_matrix = confusion_matrix(labels, predictions) \n# plot the confusion matrix\nfig,ax = plt.subplots(figsize=(8, 8))\nsb.heatmap(conf_matrix, annot=True, linewidths=0.01,cmap=\"Greens\",linecolor=\"gray\", fmt= '.1f',ax=ax)\nplt.xlabel(\"Predicted Class\")\nplt.ylabel(\"True Class\")\nplt.title(\"Confusion Matrix\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-09T13:04:20.794391Z","iopub.execute_input":"2021-11-09T13:04:20.794886Z","iopub.status.idle":"2021-11-09T13:06:14.856370Z","shell.execute_reply.started":"2021-11-09T13:04:20.794830Z","shell.execute_reply":"2021-11-09T13:06:14.854826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To be CONTINUED...","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}