{"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":"### Hyperparameters","metadata":{}},{"cell_type":"code","source":"batch_size = 64\ndropout = 0.4\nepochs = 20\nhl_units = 128 # Hidden layer\nkernel_size = 3\nfilters_1 = 64 # Filters in the first convolutional module\nfilters_2 = 128\nfilters_3 = 256\npool_size = 2\nvalidation_split = 0.2","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:19:34.191840Z","iopub.execute_input":"2023-08-04T20:19:34.192716Z","iopub.status.idle":"2023-08-04T20:19:34.205798Z","shell.execute_reply.started":"2023-08-04T20:19:34.192683Z","shell.execute_reply":"2023-08-04T20:19:34.204890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training data","metadata":{}},{"cell_type":"code","source":"!pip install -q py7zr","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:19:48.297125Z","iopub.execute_input":"2023-08-04T20:19:48.297510Z","iopub.status.idle":"2023-08-04T20:20:03.875071Z","shell.execute_reply.started":"2023-08-04T20:19:48.297480Z","shell.execute_reply":"2023-08-04T20:20:03.873806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nos.getcwd()","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:20:06.768494Z","iopub.execute_input":"2023-08-04T20:20:06.768908Z","iopub.status.idle":"2023-08-04T20:20:06.776031Z","shell.execute_reply.started":"2023-08-04T20:20:06.768872Z","shell.execute_reply":"2023-08-04T20:20:06.774938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import py7zr\n\nwith py7zr.SevenZipFile('../input/cifar-10/train.7z', mode='r') as z:\n    z.extractall('./data')","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:20:29.644749Z","iopub.execute_input":"2023-08-04T20:20:29.645144Z","iopub.status.idle":"2023-08-04T20:21:27.926028Z","shell.execute_reply.started":"2023-08-04T20:20:29.645111Z","shell.execute_reply":"2023-08-04T20:21:27.924998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with py7zr.SevenZipFile('../input/cifar-10/test.7z', mode='r') as z:\n    z.extractall('./data')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\n\nimages = []\nimage_ids = []\n\ndef get_image_id(filename):\n    return int(filename.split('/')[-1].split('.')[0])\n\n# Order of files is not guaranteed\nfor filename in os.listdir('./data/train'):\n    image = cv2.imread(os.path.join('./data/train', filename))\n    images.append(image)\n    \n    image_ids.append(get_image_id(filename))\n\nimage_ids[:5]","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:22:36.124245Z","iopub.execute_input":"2023-08-04T20:22:36.124996Z","iopub.status.idle":"2023-08-04T20:22:40.621868Z","shell.execute_reply.started":"2023-08-04T20:22:36.124960Z","shell.execute_reply":"2023-08-04T20:22:40.620750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = np.array(images, dtype=np.float32)\n\n# Normalize pixel values\nx_train = images / 255.0\nx_train.shape","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:22:41.660919Z","iopub.execute_input":"2023-08-04T20:22:41.661266Z","iopub.status.idle":"2023-08-04T20:22:42.053804Z","shell.execute_reply.started":"2023-08-04T20:22:41.661237Z","shell.execute_reply":"2023-08-04T20:22:42.052522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training labels","metadata":{}},{"cell_type":"code","source":"import csv\n\nlabels = []\n\nwith open('../input/cifar-10/trainLabels.csv', 'r') as f:\n    iter = csv.reader(f, delimiter=',')\n    next(iter, None)  # Skip the header\n    \n    for row in iter:\n        labels.append(row[1])\n\nunq_labels = list(set(labels))\nunq_labels","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:22:44.096253Z","iopub.execute_input":"2023-08-04T20:22:44.096667Z","iopub.status.idle":"2023-08-04T20:22:44.148107Z","shell.execute_reply.started":"2023-08-04T20:22:44.096636Z","shell.execute_reply":"2023-08-04T20:22:44.146993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Y_train = np.array([unq_labels.index(labels[image_id-1]) for image_id in image_ids])\nY_train.shape","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:22:46.639877Z","iopub.execute_input":"2023-08-04T20:22:46.640240Z","iopub.status.idle":"2023-08-04T20:22:46.679851Z","shell.execute_reply.started":"2023-08-04T20:22:46.640211Z","shell.execute_reply":"2023-08-04T20:22:46.678972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# One-hot encoding\nimport tensorflow as tf\n\ny_train = tf.keras.utils.to_categorical(Y_train, len(unq_labels))\nlen(y_train)","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:22:49.262588Z","iopub.execute_input":"2023-08-04T20:22:49.262975Z","iopub.status.idle":"2023-08-04T20:22:59.639799Z","shell.execute_reply.started":"2023-08-04T20:22:49.262946Z","shell.execute_reply":"2023-08-04T20:22:59.638847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Define the model","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import activations, layers, models\n\nmodel = models.Sequential([\n    layers.Conv2D(filters_1, kernel_size, activation=tf.nn.relu, input_shape=x_train[0].shape, padding=\"same\"),\n    layers.BatchNormalization(),\n    layers.MaxPool2D(pool_size=pool_size),\n    layers.Dropout(dropout),\n    \n    layers.Conv2D(filters_2, kernel_size, activation=tf.nn.relu, padding=\"same\"),\n    layers.BatchNormalization(),\n    layers.MaxPool2D(pool_size=pool_size),\n    layers.Dropout(dropout),\n    \n    layers.Conv2D(filters_3, kernel_size, activation=tf.nn.relu, padding=\"same\"),\n    layers.BatchNormalization(),\n    layers.MaxPool2D(pool_size=pool_size),\n    layers.Dropout(dropout),\n\n    layers.Flatten(),\n    \n    layers.Dense(hl_units, activation=tf.nn.relu),\n    layers.BatchNormalization(),\n    layers.Dropout(dropout),\n\n    layers.Dense(len(unq_labels), activation=tf.nn.softmax)\n])\n\nmodel.compile(\n    optimizer='adam',\n    loss=tf.keras.losses.CategoricalCrossentropy(),\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:23:04.363309Z","iopub.execute_input":"2023-08-04T20:23:04.364043Z","iopub.status.idle":"2023-08-04T20:23:09.171875Z","shell.execute_reply.started":"2023-08-04T20:23:04.364008Z","shell.execute_reply":"2023-08-04T20:23:09.170934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:23:12.196124Z","iopub.execute_input":"2023-08-04T20:23:12.196474Z","iopub.status.idle":"2023-08-04T20:23:12.255901Z","shell.execute_reply.started":"2023-08-04T20:23:12.196444Z","shell.execute_reply":"2023-08-04T20:23:12.254977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train and evaluate","metadata":{}},{"cell_type":"code","source":"callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)\n\nhistory = model.fit(x_train,\n                    y_train,\n                    batch_size=batch_size,\n                    callbacks=[callback],\n                    epochs=epochs,\n                    shuffle=True,\n                    validation_split=validation_split)","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:23:16.184061Z","iopub.execute_input":"2023-08-04T20:23:16.184427Z","iopub.status.idle":"2023-08-04T20:25:16.124076Z","shell.execute_reply.started":"2023-08-04T20:23:16.184384Z","shell.execute_reply":"2023-08-04T20:25:16.122947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import pyplot as plt\n\nplt.plot(history.history['accuracy'], label='acc')\nplt.plot(history.history['val_accuracy'], label='val_acc')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:26:08.543023Z","iopub.execute_input":"2023-08-04T20:26:08.543406Z","iopub.status.idle":"2023-08-04T20:26:41.362982Z","shell.execute_reply.started":"2023-08-04T20:26:08.543374Z","shell.execute_reply":"2023-08-04T20:26:41.361775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['loss'], label='loss')\nplt.plot(history.history['val_loss'], label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-04T20:26:41.366081Z","iopub.execute_input":"2023-08-04T20:26:41.366386Z","iopub.status.idle":"2023-08-04T20:26:41.632461Z","shell.execute_reply.started":"2023-08-04T20:26:41.366359Z","shell.execute_reply":"2023-08-04T20:26:41.631414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Predict and output predictions","metadata":{}},{"cell_type":"code","source":"test_images = []\ntest_ids = []\n\nfor filename in os.listdir('./data/test'):\n    image = cv2.imread(os.path.join('./data/test', filename))\n\n    test_images.append(image)\n    test_ids.append(get_image_id(filename))\n\ntest_images = np.array(test_images, dtype=np.float32)\ntest_images /= 255.0    ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To avoid OOM issues\ntest_image_batches = np.array_split(test_images, 50)\ntest_id_batches = np.array_split(test_ids, 50)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_file_path = './datasubmission.csv'\n\nos.remove(output_file_path)\n\nwith open(output_file_path, 'w') as f:\n    wrt = csv.writer(f)\n    # Write the header\n    wrt.writerow(['id', 'label'])\n\n    for batch_idx in range(len(test_image_batches)):\n        images = test_image_batches[batch_idx]\n        image_ids = test_id_batches[batch_idx]\n        \n        pred = model.predict(images)\n        \n        for image_idx in range(len(images)):\n            label_idx = np.argmax(pred[image_idx])\n            label = unq_labels[label_idx]\n            wrt.writerow([image_ids[image_idx], label])\n\nlen(test_images)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}