{"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":"markdown","source":"<a class=\"anchor\" id=\"1\"></a>\n## Table of Contents\n\n1. [Data Preparation](#2)\n1. [Data Augmentation](#3)\n1. [Build Model](#4)\n1. [Train Model](#5)\n1. [Visualization](#6)\n1. [Predict A Picture](#7)","metadata":{"_uuid":"6625458a-7a95-41fa-8442-11ac9cf7cfb7","_cell_guid":"ea7e673f-d7d4-43c9-a87f-673ac3aa5ae7","trusted":true}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport zipfile\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split","metadata":{"_uuid":"aa51a9ca-33ab-4147-8e54-606620289c81","_cell_guid":"e4016ffe-c15b-4040-b360-67aee8f3fd1f","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:29.896890Z","iopub.execute_input":"2023-05-10T01:24:29.898267Z","iopub.status.idle":"2023-05-10T01:24:29.905170Z","shell.execute_reply.started":"2023-05-10T01:24:29.898200Z","shell.execute_reply":"2023-05-10T01:24:29.903859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"2\"></a>\n**Data Preparation**","metadata":{"_uuid":"73e0ddf0-c9e6-4a1f-be7e-91be92c379a7","_cell_guid":"a47f8ae3-b81f-42ad-a18e-041d1db01156","trusted":true}},{"cell_type":"code","source":"# unzip files\nif(not os.path.exists(\"./train\")):\n    \n    with zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n        z.extractall(\".\")\n\n    with zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n        z.extractall(\".\")","metadata":{"_uuid":"f466990a-191c-437c-9eb3-159dd5abd3a4","_cell_guid":"069e001f-7123-4be1-a7d5-b0214c8e854c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:29.907751Z","iopub.execute_input":"2023-05-10T01:24:29.908376Z","iopub.status.idle":"2023-05-10T01:24:29.922028Z","shell.execute_reply.started":"2023-05-10T01:24:29.908333Z","shell.execute_reply":"2023-05-10T01:24:29.920816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create dataframe\nfilenames = os.listdir(\"./train\")\ncategories = []\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        categories.append(\"dog\")\n    else:\n        categories.append(\"cat\")\n\ndf = pd.DataFrame({\n    'filename': filenames,\n    'label': categories\n})\ndf.head()","metadata":{"_uuid":"4800ecf0-9207-4ddf-a8dd-fb80373692b1","_cell_guid":"4a43ae1e-0d9c-4cd9-a567-3ea49f1c16ce","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:29.923403Z","iopub.execute_input":"2023-05-10T01:24:29.923775Z","iopub.status.idle":"2023-05-10T01:24:29.991403Z","shell.execute_reply.started":"2023-05-10T01:24:29.923742Z","shell.execute_reply":"2023-05-10T01:24:29.990204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df['label'].value_counts())\nprint(df['label'].value_counts().plot.bar())","metadata":{"_uuid":"b1b58ef3-aa96-49a9-b2ec-92738199c838","_cell_guid":"0d5f9008-08bb-4802-b2c6-fb47c4a7b9eb","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:29.993740Z","iopub.execute_input":"2023-05-10T01:24:29.994132Z","iopub.status.idle":"2023-05-10T01:24:30.260026Z","shell.execute_reply.started":"2023-05-10T01:24:29.994099Z","shell.execute_reply":"2023-05-10T01:24:30.259026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(filenames[2000])\nimage = load_img(\"./train/\"+filenames[2000])\nplt.imshow(image)","metadata":{"_uuid":"d9c83526-5441-4042-ad76-3b7f62ecc238","_cell_guid":"e80bed3b-8200-41f4-8e6e-80c53bbae56a","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:30.261600Z","iopub.execute_input":"2023-05-10T01:24:30.262864Z","iopub.status.idle":"2023-05-10T01:24:30.562526Z","shell.execute_reply.started":"2023-05-10T01:24:30.262814Z","shell.execute_reply":"2023-05-10T01:24:30.561161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# show an example of an image\nprint(filenames[0])\nimage = load_img(\"./train/\"+filenames[0])\nplt.imshow(image)","metadata":{"_uuid":"daf0e65f-1bbf-4d26-b287-8b2d60f44adc","_cell_guid":"8e1c8fa6-b2b1-4941-9ad4-6a26240f3d81","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:30.564470Z","iopub.execute_input":"2023-05-10T01:24:30.564914Z","iopub.status.idle":"2023-05-10T01:24:30.851841Z","shell.execute_reply.started":"2023-05-10T01:24:30.564832Z","shell.execute_reply":"2023-05-10T01:24:30.850621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split dataset into train and validation\ntrain_df, validate_df = train_test_split(df, test_size=0.20, random_state=42)\ntrain_df = train_df.reset_index()\nvalidate_df = validate_df.reset_index()\nprint(train_df.shape[0])\nprint(validate_df.shape[0])","metadata":{"_uuid":"f0a2d156-fc0f-40da-99f4-7eaee57adaa8","_cell_guid":"1b6b488e-385f-4cc0-b6ff-2b8b4cde63e8","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:30.853902Z","iopub.execute_input":"2023-05-10T01:24:30.854718Z","iopub.status.idle":"2023-05-10T01:24:30.870290Z","shell.execute_reply.started":"2023-05-10T01:24:30.854668Z","shell.execute_reply":"2023-05-10T01:24:30.869363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"3\"></a>\n**Data Augmentation**","metadata":{"_uuid":"f12824d6-b5ff-4bd9-8cd6-a99c39ffc1e5","_cell_guid":"f3932d52-25af-4602-88b4-f354324b9c5a","trusted":true}},{"cell_type":"code","source":"# train dataset augmentation\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255, #convert rbg values to within 0-1\n    rotation_range=15, \n    shear_range=0.1, #how much you want to slant\n    zoom_range=0.2, \n    horizontal_flip=True,\n    width_shift_range=0.1, #horizontal transformation\n    height_shift_range=0.1 #vertical transformation\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, #which dataframe\n    \"./train\", #under which path (folder)?\n    x_col='filename', #which column contains the filenames?\n    y_col='label', #which column contains the labels?\n    target_size=(128,128), #size of the generated image\n    class_mode='categorical', #why type of labels (dogs and cats)\n    batch_size=15 #process how many image for one iteration?\n)","metadata":{"_uuid":"b4cad7a0-9c7b-4bcb-9798-c069b07f1104","_cell_guid":"263ee04a-e414-4019-bac3-e2c57a7141d8","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:30.871881Z","iopub.execute_input":"2023-05-10T01:24:30.872476Z","iopub.status.idle":"2023-05-10T01:24:31.542682Z","shell.execute_reply.started":"2023-05-10T01:24:30.872442Z","shell.execute_reply":"2023-05-10T01:24:31.541280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# validation dataset augmentation\nvalidation_datagen = ImageDataGenerator(\n    rescale=1./255\n)\n\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    validate_df, \n    \"./train\", \n    x_col='filename',\n    y_col='label',\n    target_size=(128,128),\n    class_mode='categorical',\n    batch_size=15\n)","metadata":{"_uuid":"0883d50d-1792-4217-be43-8702d759637c","_cell_guid":"4b506c39-ee52-4cfd-be1d-c337f12486ca","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:31.547435Z","iopub.execute_input":"2023-05-10T01:24:31.547815Z","iopub.status.idle":"2023-05-10T01:24:31.633479Z","shell.execute_reply.started":"2023-05-10T01:24:31.547782Z","shell.execute_reply":"2023-05-10T01:24:31.632188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# show an example of dataset augmentation (not necesary to build model, this is just to visualize)\nexample_df = train_df.head(1)\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df, \n    \"./train\", \n    x_col='filename',\n    y_col='label',\n    target_size=(128,128),\n    class_mode='categorical'\n)\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 example_generator:\n        image = X_batch[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","metadata":{"_uuid":"391838a3-3c42-4e4e-a754-2ec0c61eab27","_cell_guid":"378c986c-c8ed-479b-ae78-b213027211dd","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:31.634804Z","iopub.execute_input":"2023-05-10T01:24:31.635171Z","iopub.status.idle":"2023-05-10T01:24:33.528055Z","shell.execute_reply.started":"2023-05-10T01:24:31.635134Z","shell.execute_reply":"2023-05-10T01:24:33.526788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"4\"></a>\n**Build Model**","metadata":{"_uuid":"5a5e20b2-6340-4b41-b1b5-0fc3ebcd290d","_cell_guid":"421640ee-dd2b-4939-a6dd-b679acc57303","trusted":true}},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization\n\nmodel = Sequential()","metadata":{"_uuid":"2347f9b5-ef3d-4b9d-8447-878785f1333c","_cell_guid":"a9a8e70c-d799-430c-ac66-35c98bb23ba2","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:33.529654Z","iopub.execute_input":"2023-05-10T01:24:33.530117Z","iopub.status.idle":"2023-05-10T01:24:33.598138Z","shell.execute_reply.started":"2023-05-10T01:24:33.530072Z","shell.execute_reply":"2023-05-10T01:24:33.597127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 3)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.summary()","metadata":{"_uuid":"76d745ea-0d2d-4b18-899a-aefcc84af627","_cell_guid":"4640ecbe-deca-42f5-9475-5dfd717e3b71","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:33.599544Z","iopub.execute_input":"2023-05-10T01:24:33.600231Z","iopub.status.idle":"2023-05-10T01:24:33.761153Z","shell.execute_reply.started":"2023-05-10T01:24:33.600192Z","shell.execute_reply":"2023-05-10T01:24:33.759815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\nmodel.add(Dense(2, activation='softmax')) # 2 because we have cat and dog classes\n\nmodel.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])\n\nmodel.summary()","metadata":{"_uuid":"671eae52-55ae-40dd-beb3-8f442f81cfa7","_cell_guid":"bbcbaa06-ce46-4c4b-b7bd-b941a60989cc","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:33.762930Z","iopub.execute_input":"2023-05-10T01:24:33.763644Z","iopub.status.idle":"2023-05-10T01:24:34.168515Z","shell.execute_reply.started":"2023-05-10T01:24:33.763606Z","shell.execute_reply":"2023-05-10T01:24:34.167068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"5\"></a>\n**Train Model**","metadata":{"_uuid":"d25447a1-5b66-449c-8a74-8ceb160e6556","_cell_guid":"e8d7ee92-7ed2-489a-ad72-f529a68fbf5c","trusted":true}},{"cell_type":"code","source":"epochs=3\nhistory = model.fit_generator(\n    train_generator, \n    epochs=epochs,\n    validation_data=validation_generator,\n    validation_steps=validate_df.shape[0]//64,\n    steps_per_epoch=train_df.shape[0]//64,\n)","metadata":{"_uuid":"dc43821b-f0b6-478a-aed8-f08ca14007e9","_cell_guid":"5f3428a6-7c2a-46fb-bb5a-f25b7a73b911","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:24:34.170609Z","iopub.execute_input":"2023-05-10T01:24:34.171073Z","iopub.status.idle":"2023-05-10T01:31:07.006714Z","shell.execute_reply.started":"2023-05-10T01:24:34.171037Z","shell.execute_reply":"2023-05-10T01:31:07.005692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"6\"></a>\n**Visualization**","metadata":{"_uuid":"7902ac31-75c8-4c54-a1b3-1ea16dd07a28","_cell_guid":"63644ed5-9d3b-4c1a-aa11-0c58408dbb51","trusted":true}},{"cell_type":"code","source":"# accuracy plot\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper left')\nplt.show()","metadata":{"_uuid":"5cf88b83-0322-45f5-a16c-ac4805e89682","_cell_guid":"aa79c751-1f15-435a-986a-2a0f4ef483ce","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-05-10T01:31:07.008973Z","iopub.execute_input":"2023-05-10T01:31:07.009763Z","iopub.status.idle":"2023-05-10T01:31:07.199766Z","shell.execute_reply.started":"2023-05-10T01:31:07.009715Z","shell.execute_reply":"2023-05-10T01:31:07.198462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"7\"></a>\n**Predict A Picture**","metadata":{}},{"cell_type":"code","source":"from PIL import Image\nimport numpy as np\nfrom keras.preprocessing.image import img_to_array\n\nimg = Image.open('./train/cat.1.jpg') # change the path\nnew_width  = 128\nnew_height = 128\nimg = img.resize((new_width, new_height), Image.ANTIALIAS)\nimg","metadata":{"execution":{"iopub.status.busy":"2023-05-10T02:25:57.563406Z","iopub.execute_input":"2023-05-10T02:25:57.563938Z","iopub.status.idle":"2023-05-10T02:25:57.587703Z","shell.execute_reply.started":"2023-05-10T02:25:57.563903Z","shell.execute_reply":"2023-05-10T02:25:57.586347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = img_to_array(img)\nimg = np.expand_dims(img, axis=0) \nimg = img/255\n\npred = model.predict(img)[0]\nprint(pred) #[% cat, % dog]\nindex = np.argmax(pred)\nprint(index) #0 -> cat, 1 -> dog","metadata":{"execution":{"iopub.status.busy":"2023-05-10T02:25:59.822155Z","iopub.execute_input":"2023-05-10T02:25:59.822577Z","iopub.status.idle":"2023-05-10T02:25:59.903297Z","shell.execute_reply.started":"2023-05-10T02:25:59.822544Z","shell.execute_reply":"2023-05-10T02:25:59.902102Z"},"trusted":true},"execution_count":null,"outputs":[]}]}