{"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":"# About today's session?\n\n## Transfer Learning?\nThe reuse of a previously learned model on a new problem is known as transfer learning.\n\n\n![](https://data-science-blog.com/wp-content/uploads/2022/04/usual-machine-learning-vs-transfer-learning.png)\n\n\n## Cats vs Dogs\nWe are going to build and train a deep neural network that can differentiate between an image of a cat and a dog using transfer learning.","metadata":{}},{"cell_type":"markdown","source":"![](https://unsplash.com/photos/-_gMskl-uoc/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8NDB8fGZ1bm55JTIwZG9nfGVufDB8MHx8fDE2NTkzODg2NDg&force=true&w=1920)","metadata":{}},{"cell_type":"markdown","source":"## Importing Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\nimport os\nprint(os.listdir(\"../input\"))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-08-09T10:57:26.867303Z","iopub.execute_input":"2022-08-09T10:57:26.867622Z","iopub.status.idle":"2022-08-09T10:57:26.874030Z","shell.execute_reply.started":"2022-08-09T10:57:26.867559Z","shell.execute_reply":"2022-08-09T10:57:26.873052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Constants","metadata":{}},{"cell_type":"code","source":"IMAGE_WIDTH=128\nIMAGE_HEIGHT=128\nIMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)\nIMAGE_CHANNELS=3\nINPUT_SHAPE = (IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)","metadata":{"execution":{"iopub.status.busy":"2022-08-09T10:57:27.096984Z","iopub.execute_input":"2022-08-09T10:57:27.097299Z","iopub.status.idle":"2022-08-09T10:57:27.101889Z","shell.execute_reply.started":"2022-08-09T10:57:27.097244Z","shell.execute_reply":"2022-08-09T10:57:27.101032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build Model\n\n<img src=\"https://i.imgur.com/ebkMGGu.jpg\" width=\"100%\"/>","metadata":{"_uuid":"b244e6b7715a04fc6df92dd6dfa3d35c473ca600"}},{"cell_type":"markdown","source":"* **Input Layer**: It represent input image data. It will reshape image into single dimension array. Example your image is 64x64 = 4096, it will convert to (4096,1) array.\n* **Conv Layer**: This layer will extract features from image.\n* **Pooling Layer**: This layerreduce the spatial volume of input image after convolution.\n* **Fully Connected Layer**: It connect the network from a layer to another layer\n* **Output Layer**: It is the predicted values layer. ","metadata":{}},{"cell_type":"markdown","source":"## The crude way","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization\n\nmodel = Sequential()\n\nmodel.add(Conv2D(32, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)))\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.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid')) # 2 because we have cat and dog classes\n\n\n#adam = adaptive moment estimation\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n\nmodel.summary()","metadata":{"_uuid":"8c9f833c1441b657c779844912d0b8028218d454","execution":{"iopub.status.busy":"2022-08-09T10:57:27.228369Z","iopub.execute_input":"2022-08-09T10:57:27.228638Z","iopub.status.idle":"2022-08-09T10:57:27.695674Z","shell.execute_reply.started":"2022-08-09T10:57:27.228587Z","shell.execute_reply":"2022-08-09T10:57:27.694847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Using Transfer Learning","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50, Xception\n\nbase_model = Xception(\n    include_top=False,\n    weights=\"imagenet\",\n    input_shape = INPUT_SHAPE,\n)\n\nmodel_1 = Sequential()\nmodel_1.add(base_model)\n\nmodel_1.add(Flatten())\nmodel_1.add(Dense(512, activation='relu'))\nmodel_1.add(Dropout(0.5))\nmodel_1.add(Dense(1, activation='sigmoid')) # 2 because we have cat and dog classes\n\n\n#adam = adaptive moment estimation\nmodel_1.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n\nmodel_1.summary()","metadata":{"execution":{"iopub.status.busy":"2022-08-09T10:57:27.699683Z","iopub.execute_input":"2022-08-09T10:57:27.699914Z","iopub.status.idle":"2022-08-09T10:57:46.025778Z","shell.execute_reply.started":"2022-08-09T10:57:27.699867Z","shell.execute_reply":"2022-08-09T10:57:46.025121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Let's visualize the model","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.utils import plot_model\n\nplot_model(model_1, to_file='model_1_plot.png', show_shapes=True, show_layer_names=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-09T10:57:46.027263Z","iopub.execute_input":"2022-08-09T10:57:46.027730Z","iopub.status.idle":"2022-08-09T10:57:46.211944Z","shell.execute_reply.started":"2022-08-09T10:57:46.027676Z","shell.execute_reply":"2022-08-09T10:57:46.210341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Setting batch size\ntrain_dir = \"../input/cat-and-dog/training_set/training_set/\"   #Setting training directory\nvalidation_dir = \"../input/cat-and-dog/test_set/test_set/\" \nbatch_size=32","metadata":{"_uuid":"ae3dec0361f0443132d0309d3b883ee80070cf9f","execution":{"iopub.status.busy":"2022-08-09T10:57:46.213861Z","iopub.execute_input":"2022-08-09T10:57:46.214154Z","iopub.status.idle":"2022-08-09T10:57:46.219152Z","shell.execute_reply.started":"2022-08-09T10:57:46.214105Z","shell.execute_reply":"2022-08-09T10:57:46.218366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Traning Generator","metadata":{"_uuid":"ff760be9104f7d9492467b8d9d3405011aa77d11"}},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=15,\n    rescale=1./255,\n    shear_range=0.1,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=IMAGE_SIZE,\n    class_mode='binary',\n    batch_size=batch_size\n)","metadata":{"_uuid":"4d1c7818703a8a4bac5c036fdea45972aa9e5e9e","execution":{"iopub.status.busy":"2022-08-09T10:57:46.220474Z","iopub.execute_input":"2022-08-09T10:57:46.221059Z","iopub.status.idle":"2022-08-09T10:57:47.855279Z","shell.execute_reply.started":"2022-08-09T10:57:46.221003Z","shell.execute_reply":"2022-08-09T10:57:47.854433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Validation Generator","metadata":{"_uuid":"859c7b2857939c19fd2e3bb32839c9f7deb5aa3f"}},{"cell_type":"code","source":"validation_datagen = ImageDataGenerator(rescale=1./255)\nvalidation_generator = validation_datagen.flow_from_directory(\n    validation_dir,\n    target_size=IMAGE_SIZE,\n    class_mode='binary',\n    batch_size=batch_size\n)","metadata":{"_uuid":"7925e16bcacc89f4484fb6fe47e54d6420af732e","execution":{"iopub.status.busy":"2022-08-09T10:57:47.856308Z","iopub.execute_input":"2022-08-09T10:57:47.860809Z","iopub.status.idle":"2022-08-09T10:57:47.972315Z","shell.execute_reply.started":"2022-08-09T10:57:47.856513Z","shell.execute_reply":"2022-08-09T10:57:47.971450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# See how our generator work","metadata":{"_uuid":"6e17fc1f002fedd60febb78fee5e81770640b909"}},{"cell_type":"code","source":"plt.figure(figsize=(8, 8))\nfor i in range(0, 15):\n    plt.subplot(5, 3, i+1)\n    for img in next(train_generator):\n        image = img[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","metadata":{"_uuid":"23d923dba747f8b47dc75569244cecc6f70df321","execution":{"iopub.status.busy":"2022-08-09T10:57:47.974290Z","iopub.execute_input":"2022-08-09T10:57:47.974569Z","iopub.status.idle":"2022-08-09T10:57:53.344849Z","shell.execute_reply.started":"2022-08-09T10:57:47.974508Z","shell.execute_reply":"2022-08-09T10:57:53.344123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Let's train the model ","metadata":{"_uuid":"5cd8df64e794ed17de326b613a9819e7da977a0e"}},{"cell_type":"code","source":"epochs=5\nhistory = model_1.fit_generator(\n    train_generator, \n    epochs=epochs,\n    validation_data=validation_generator,\n    validation_steps=train_generator.samples//batch_size,\n    steps_per_epoch=validation_generator.samples//batch_size,\n)","metadata":{"_uuid":"0836a4cc8aa0abf603e0f96573c0c4ff383ad56b","execution":{"iopub.status.busy":"2022-08-09T10:57:53.346178Z","iopub.execute_input":"2022-08-09T10:57:53.346702Z","iopub.status.idle":"2022-08-09T11:05:04.180182Z","shell.execute_reply.started":"2022-08-09T10:57:53.346651Z","shell.execute_reply":"2022-08-09T11:05:04.179485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save Model","metadata":{"_uuid":"aa1fbc4081ae0de2993188b2bf658a0be5bc0687"}},{"cell_type":"code","source":"model.save_weights(\"model.h5\")","metadata":{"_uuid":"67575a4decdaf79a915d23151626b784ffa82642","execution":{"iopub.status.busy":"2022-08-09T11:07:02.499015Z","iopub.execute_input":"2022-08-09T11:07:02.499313Z","iopub.status.idle":"2022-08-09T11:07:12.327118Z","shell.execute_reply.started":"2022-08-09T11:07:02.499259Z","shell.execute_reply":"2022-08-09T11:07:12.326405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Virtualize Training","metadata":{"_uuid":"1b76c0a9040bc0babf0a453e567e41e22f8a1e0e"}},{"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 8))\nax1.plot(history.history['loss'], color='b', label=\"Training loss\")\nax1.plot(history.history['val_loss'], color='r', label=\"validation loss\")\nax1.set_xticks(np.arange(1, epochs, 1))\nax1.set_yticks(np.arange(0, 1, 0.1))\n\nax2.plot(history.history['acc'], color='b', label=\"Training accuracy\")\nax2.plot(history.history['val_acc'], color='r',label=\"Validation accuracy\")\nax2.set_xticks(np.arange(1, epochs, 1))\n\nlegend = plt.legend(loc='best', shadow=True)\nplt.tight_layout()\nplt.show()","metadata":{"_uuid":"79055f2dc3e2abb47bea758e0464c86ca42ab431","execution":{"iopub.status.busy":"2022-08-09T11:07:12.329465Z","iopub.execute_input":"2022-08-09T11:07:12.330042Z","iopub.status.idle":"2022-08-09T11:07:12.828006Z","shell.execute_reply.started":"2022-08-09T11:07:12.329989Z","shell.execute_reply":"2022-08-09T11:07:12.827124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}