{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30747,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#imports\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport os\nimport tensorflow as tf\nimport tensorflow.keras.layers as tfl\nimport pandas as pd\n\nfrom tensorflow.keras.preprocessing import image_dataset_from_directory","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-20T11:49:42.426932Z","iopub.execute_input":"2024-07-20T11:49:42.427288Z","iopub.status.idle":"2024-07-20T11:49:54.790070Z","shell.execute_reply.started":"2024-07-20T11:49:42.427255Z","shell.execute_reply":"2024-07-20T11:49:54.789144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#seed for stable results\nseed = 7","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:49:54.791939Z","iopub.execute_input":"2024-07-20T11:49:54.792651Z","iopub.status.idle":"2024-07-20T11:49:54.797189Z","shell.execute_reply.started":"2024-07-20T11:49:54.792612Z","shell.execute_reply":"2024-07-20T11:49:54.796245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\nIMG_SIZE = (160, 160)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:49:54.798197Z","iopub.execute_input":"2024-07-20T11:49:54.798484Z","iopub.status.idle":"2024-07-20T11:49:54.827848Z","shell.execute_reply.started":"2024-07-20T11:49:54.798459Z","shell.execute_reply":"2024-07-20T11:49:54.826907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip -qq ../input/dogs-vs-cats/test1.zip -d ../working\n!unzip -qq ../input/dogs-vs-cats/train.zip -d ../working\n\n!mkdir ../working/train/dog\n!mkdir ../working/train/cat\n\n!cd ../working/train ; ls  | grep \"cat.*.jpg\" | xargs mv -t cat/\n!cd ../working/train ; ls  | grep \"dog.*.jpg\" | xargs mv -t dog/\n\n!ls -l ../working/train/dog | wc -l\n!ls -l ../working/train/cat | wc -l","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:49:54.830176Z","iopub.execute_input":"2024-07-20T11:49:54.830494Z","iopub.status.idle":"2024-07-20T11:50:18.938822Z","shell.execute_reply.started":"2024-07-20T11:49:54.830469Z","shell.execute_reply":"2024-07-20T11:50:18.937464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"directory = \"../working/train\"\ntrain_dataset = image_dataset_from_directory(directory,\n                                             shuffle=True,\n                                             batch_size=BATCH_SIZE,\n                                             image_size=IMG_SIZE,\n                                             validation_split=0.8,\n                                             subset='training',\n                                             seed=seed)\n\nvalidation_dataset = image_dataset_from_directory(directory,\n                                             shuffle=True,\n                                             batch_size=BATCH_SIZE,\n                                             image_size=IMG_SIZE,\n                                             validation_split=0.2,\n                                             subset='validation',\n                                             seed=seed)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:18.940635Z","iopub.execute_input":"2024-07-20T11:50:18.941012Z","iopub.status.idle":"2024-07-20T11:50:25.808078Z","shell.execute_reply.started":"2024-07-20T11:50:18.940974Z","shell.execute_reply":"2024-07-20T11:50:25.807076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset.class_names","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:25.809428Z","iopub.execute_input":"2024-07-20T11:50:25.809735Z","iopub.status.idle":"2024-07-20T11:50:25.816605Z","shell.execute_reply.started":"2024-07-20T11:50:25.809709Z","shell.execute_reply":"2024-07-20T11:50:25.815726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_names = train_dataset.class_names\nplt.figure(figsize=(10, 10))\nfor images, labels in train_dataset.take(1):\n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        plt.imshow(images[i].numpy().astype(\"uint8\"))\n        plt.title(class_names[labels[i]])\n        plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:25.817778Z","iopub.execute_input":"2024-07-20T11:50:25.818124Z","iopub.status.idle":"2024-07-20T11:50:27.189866Z","shell.execute_reply.started":"2024-07-20T11:50:25.818090Z","shell.execute_reply":"2024-07-20T11:50:27.188877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#prefetching settings\nAUTOTUNE = tf.data.experimental.AUTOTUNE\ntrain_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:27.191180Z","iopub.execute_input":"2024-07-20T11:50:27.191523Z","iopub.status.idle":"2024-07-20T11:50:27.197731Z","shell.execute_reply.started":"2024-07-20T11:50:27.191497Z","shell.execute_reply":"2024-07-20T11:50:27.196790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def data_augmenter():\n    '''\n    Create a Sequential model composed of 2 layers\n    Returns:\n        tf.keras.Sequential\n    '''\n    data_augmentation = tf.keras.Sequential()\n    data_augmentation.add(tfl.RandomFlip('horizontal'))\n    data_augmentation.add(tfl.RandomRotation(0.2))\n    return data_augmentation","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:27.198962Z","iopub.execute_input":"2024-07-20T11:50:27.199309Z","iopub.status.idle":"2024-07-20T11:50:27.210338Z","shell.execute_reply.started":"2024-07-20T11:50:27.199279Z","shell.execute_reply":"2024-07-20T11:50:27.209341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_augmentation = data_augmenter()\nfor image, _ in train_dataset.take(1):\n    plt.figure(figsize=(10, 10))\n    first_image = image[0]\n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        augmented_image = data_augmentation(tf.expand_dims(first_image, 0))\n        plt.imshow(augmented_image[0] / 255)\n        plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:27.213961Z","iopub.execute_input":"2024-07-20T11:50:27.214570Z","iopub.status.idle":"2024-07-20T11:50:29.797515Z","shell.execute_reply.started":"2024-07-20T11:50:27.214534Z","shell.execute_reply":"2024-07-20T11:50:29.796510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#get preprocessing layer of base model\npreprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input\n\n\ndef classification_model(image_shape=IMG_SIZE, data_augmentation=data_augmenter()):\n    ''' Define a tf.keras model for binary classification out of the MobileNetV2 model\n    Arguments:\n        image_shape -- Image width and height\n        data_augmentation -- data augmentation function\n    Returns:\n    Returns:\n        tf.keras.model\n    '''\n    \n    \n    input_shape = IMG_SIZE + (3,)\n    base_model = tf.keras.applications.MobileNetV2(input_shape=input_shape,\n                                                   include_top=False, \n                                                   weights='imagenet') # From imageNet\n    \n   \n    #freeze base model\n    base_model.trainable = False \n\n    inputs = tf.keras.Input(shape=input_shape) \n    x = data_augmentation(inputs)\n    x = preprocess_input(x)\n    x = base_model(x, training=False) \n    x = tfl.GlobalAveragePooling2D()(x)\n    x = tfl.Dropout(0.2)(x)\n    outputs = tfl.Dense(1)(x)\n    \n    model = tf.keras.Model(inputs, outputs)\n    return model","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:29.798715Z","iopub.execute_input":"2024-07-20T11:50:29.799025Z","iopub.status.idle":"2024-07-20T11:50:29.815408Z","shell.execute_reply.started":"2024-07-20T11:50:29.798998Z","shell.execute_reply":"2024-07-20T11:50:29.814419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2 = classification_model(IMG_SIZE, data_augmentation)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:29.816882Z","iopub.execute_input":"2024-07-20T11:50:29.817193Z","iopub.status.idle":"2024-07-20T11:50:31.297789Z","shell.execute_reply.started":"2024-07-20T11:50:29.817160Z","shell.execute_reply":"2024-07-20T11:50:31.296765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_learning_rate = 0.001\nmodel2.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),\n              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:31.298990Z","iopub.execute_input":"2024-07-20T11:50:31.299288Z","iopub.status.idle":"2024-07-20T11:50:31.314227Z","shell.execute_reply.started":"2024-07-20T11:50:31.299262Z","shell.execute_reply":"2024-07-20T11:50:31.313329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"initial_epochs = 10\nhistory = model2.fit(train_dataset, validation_data=validation_dataset, epochs=initial_epochs)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:50:31.315847Z","iopub.execute_input":"2024-07-20T11:50:31.316114Z","iopub.status.idle":"2024-07-20T11:52:10.582837Z","shell.execute_reply.started":"2024-07-20T11:50:31.316090Z","shell.execute_reply":"2024-07-20T11:52:10.582003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#plot metrics\nacc = [0.] + history.history['accuracy']\nval_acc = [0.] + history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nplt.figure(figsize=(8, 8))\nplt.subplot(2, 1, 1)\nplt.plot(acc, label='Training Accuracy')\nplt.plot(val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.ylabel('Accuracy')\nplt.ylim([min(plt.ylim()),1])\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(2, 1, 2)\nplt.plot(loss, label='Training Loss')\nplt.plot(val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.ylabel('Cross Entropy')\nplt.ylim([0,1.0])\nplt.title('Training and Validation Loss')\nplt.xlabel('epoch')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:52:10.584600Z","iopub.execute_input":"2024-07-20T11:52:10.584951Z","iopub.status.idle":"2024-07-20T11:52:11.055746Z","shell.execute_reply.started":"2024-07-20T11:52:10.584917Z","shell.execute_reply":"2024-07-20T11:52:11.054880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2.summary()","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:52:11.056741Z","iopub.execute_input":"2024-07-20T11:52:11.057000Z","iopub.status.idle":"2024-07-20T11:52:11.089911Z","shell.execute_reply.started":"2024-07-20T11:52:11.056976Z","shell.execute_reply":"2024-07-20T11:52:11.089108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = model2.layers[2]\nbase_model.trainable = True\n# Let's take a look to see how many layers are in the base model\nprint(\"Number of layers in the base model: \", len(base_model.layers))","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:52:11.090929Z","iopub.execute_input":"2024-07-20T11:52:11.091202Z","iopub.status.idle":"2024-07-20T11:52:11.100392Z","shell.execute_reply.started":"2024-07-20T11:52:11.091177Z","shell.execute_reply":"2024-07-20T11:52:11.099400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fine-tune from this layer onwards\nfine_tune_at = 120\n\n### START CODE HERE\n\n# Freeze all the layers before the `fine_tune_at` layer\nfor layer in base_model.layers[:fine_tune_at]:\n    layer.trainable = False\n    \n# Define a BinaryCrossentropy loss function. Use from_logits=True\nloss_function = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n# Define an Adam optimizer with a learning rate of 0.1 * base_learning_rate\noptimizer = tf.keras.optimizers.Adam(learning_rate=base_learning_rate * 0.1)\n# Use accuracy as evaluation metric\nmetrics=['accuracy']\n\n### END CODE HERE\n\nmodel2.compile(loss=loss_function,\n              optimizer = optimizer,\n              metrics=metrics)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:52:11.101543Z","iopub.execute_input":"2024-07-20T11:52:11.101843Z","iopub.status.idle":"2024-07-20T11:52:11.117346Z","shell.execute_reply.started":"2024-07-20T11:52:11.101818Z","shell.execute_reply":"2024-07-20T11:52:11.116624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fine_tune_epochs = 5\ntotal_epochs =  initial_epochs + fine_tune_epochs\n\nhistory_fine = model2.fit(train_dataset,\n                         epochs=total_epochs,\n                         initial_epoch=history.epoch[-1],\n                         validation_data=validation_dataset)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:52:11.118512Z","iopub.execute_input":"2024-07-20T11:52:11.119313Z","iopub.status.idle":"2024-07-20T11:53:40.356150Z","shell.execute_reply.started":"2024-07-20T11:52:11.119287Z","shell.execute_reply":"2024-07-20T11:53:40.355358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_directory = \"/kaggle/working/test1\"\nfiles = os.listdir(test_directory)\nids = [os.path.splitext(f)[0] for f in files]\npredictions = []\ntest_dataset = image_dataset_from_directory(test_directory,\n                                             shuffle=False,\n                                             batch_size=512,\n                                             image_size=IMG_SIZE,\n                                             label_mode = None,\n                                             seed=seed)\n\n\nfor batch in test_dataset:\n    prediction = model2.predict(batch)\n    prediction = tf.math.sigmoid(tf.squeeze(prediction))\n    prediction = tf.cast(prediction > 0.5, tf.int32).numpy()\n    predictions.extend(prediction)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:53:40.357416Z","iopub.execute_input":"2024-07-20T11:53:40.357715Z","iopub.status.idle":"2024-07-20T11:53:57.173191Z","shell.execute_reply.started":"2024-07-20T11:53:40.357687Z","shell.execute_reply":"2024-07-20T11:53:57.172406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(ids))\nprint(len(predictions))","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:53:57.174596Z","iopub.execute_input":"2024-07-20T11:53:57.174890Z","iopub.status.idle":"2024-07-20T11:53:57.179704Z","shell.execute_reply.started":"2024-07-20T11:53:57.174862Z","shell.execute_reply":"2024-07-20T11:53:57.178819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = {'id': ids, 'label': predictions}\ndf = pd.DataFrame(data)\ndf.to_csv('submission.csv', encoding='utf-8', index=False, header=True)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:53:57.180937Z","iopub.execute_input":"2024-07-20T11:53:57.181234Z","iopub.status.idle":"2024-07-20T11:53:57.314234Z","shell.execute_reply.started":"2024-07-20T11:53:57.181208Z","shell.execute_reply":"2024-07-20T11:53:57.313492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_names = ['cat', 'dog']\nplt.figure(figsize=(10, 10))\nfor images in test_dataset.take(1):\n    prediction = model2.predict(images)\n    prediction = tf.math.sigmoid(tf.squeeze(prediction))\n    prediction = tf.cast(prediction > 0.5, tf.int32).numpy()\n    \n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        plt.imshow(images[i].numpy().astype(\"uint8\"))\n        plt.title(class_names[labels[i]])\n        plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2024-07-20T11:57:42.097707Z","iopub.execute_input":"2024-07-20T11:57:42.098157Z","iopub.status.idle":"2024-07-20T11:57:44.025101Z","shell.execute_reply.started":"2024-07-20T11:57:42.098121Z","shell.execute_reply":"2024-07-20T11:57:44.024065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}