{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-05T18:36:56.532122Z","iopub.execute_input":"2022-04-05T18:36:56.532703Z","iopub.status.idle":"2022-04-05T18:36:56.564276Z","shell.execute_reply.started":"2022-04-05T18:36:56.532607Z","shell.execute_reply":"2022-04-05T18:36:56.563610Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CIFAR-10 Image Classification with Convolutional Neural Networks\n\nIn this notebook, we will explore the task of image classification using the CIFAR-10 dataset. CIFAR-10 is a widely used benchmark dataset in the field of computer vision, consisting of 60,000 32x32 color images across 10 different classes. The goal of this project is to build a Convolutional Neural Network (CNN) model that can accurately classify these images into their respective categories.\n\nWe will start by setting up the environment and preparing the dataset, including loading the training and test data, as well as their corresponding labels. Then, we will preprocess the data and split it into training and validation sets for model training. Our chosen CNN architecture will consist of multiple convolutional and fully connected layers, carefully designed to capture and learn relevant features from the images.\n\nTo improve model performance and prevent overfitting, we will incorporate techniques such as data augmentation, batch normalization, and dropout. The model will be trained using the training set and validated on the validation set. Once training is complete, we will use the trained model to predict the classes of the test images.\n\nFinally, we will map the predicted numeric labels back to their corresponding class names and create a submission file suitable for the Kaggle competition. Throughout this notebook, we will emphasize both the theoretical concepts behind CNNs and their practical implementation using Keras and TensorFlow. Our objective is to achieve high accuracy in classifying CIFAR-10 images and gain insights into the realm of image classification using deep learning.\n\nLet's dive into the code and explore the journey of building an effective image classifier for the CIFAR-10 dataset!\n---","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport keras\nfrom keras import backend as K\n%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom matplotlib import pyplot\nfrom statistics import mean\nimport glob\nimport os\nimport cv2\nimport sys","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:36:59.212054Z","iopub.execute_input":"2022-04-05T18:36:59.212844Z","iopub.status.idle":"2022-04-05T18:37:04.377095Z","shell.execute_reply.started":"2022-04-05T18:36:59.212803Z","shell.execute_reply":"2022-04-05T18:37:04.376356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install py7zr\nimport py7zr","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:37:04.378489Z","iopub.execute_input":"2022-04-05T18:37:04.378750Z","iopub.status.idle":"2022-04-05T18:37:16.532769Z","shell.execute_reply.started":"2022-04-05T18:37:04.378715Z","shell.execute_reply":"2022-04-05T18:37:16.532024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nfrom py7zr import unpack_7zarchive\n\nshutil.register_unpack_format('7zip',['.7z'],unpack_7zarchive)\nshutil.unpack_archive('/kaggle/input/cifar-10/train.7z', '/kaggle/working/')","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:37:16.534489Z","iopub.execute_input":"2022-04-05T18:37:16.534736Z","iopub.status.idle":"2022-04-05T18:37:57.166733Z","shell.execute_reply.started":"2022-04-05T18:37:16.534702Z","shell.execute_reply":"2022-04-05T18:37:57.166010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code is used to extract the CIFAR-10 dataset from a 7z archive file. It first registers the '7zip' format with the '.7z' extension using the `shutil.register_unpack_format` function. Then, it unpacks the contents of the 'train.7z' file located in the specified input directory (\"/kaggle/input/cifar-10/train.7z\") and extracts them into the specified working directory (\"/kaggle/working/\"). This action allows you to access and use the CIFAR-10 dataset for further processing or analysis.","metadata":{}},{"cell_type":"code","source":"#with py7zr.SevenZipFile('/kaggle/input/cifar-10/train.7z', mode='r') as z:\n#    z.extractall()","metadata":{"execution":{"iopub.status.busy":"2022-03-24T18:08:13.657858Z","iopub.execute_input":"2022-03-24T18:08:13.658107Z","iopub.status.idle":"2022-03-24T18:08:13.661744Z","shell.execute_reply.started":"2022-03-24T18:08:13.658074Z","shell.execute_reply":"2022-03-24T18:08:13.660977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels = pd.read_csv(\"/kaggle/input/cifar-10/trainLabels.csv\", header=\"infer\")\n\nclasses = train_labels['label'].unique()\nprint(classes)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:40:01.207750Z","iopub.execute_input":"2022-04-05T18:40:01.208029Z","iopub.status.idle":"2022-04-05T18:40:01.252132Z","shell.execute_reply.started":"2022-04-05T18:40:01.208000Z","shell.execute_reply":"2022-04-05T18:40:01.251369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code reads the CIFAR-10 training labels from a CSV file named \"trainLabels.csv\". The labels are loaded into a pandas DataFrame called `train_labels`. It then extracts the unique classes from the 'label' column and prints them. This gives you the list of distinct classes present in the CIFAR-10 dataset, helping you understand the different categories of images that the dataset contains.","metadata":{}},{"cell_type":"code","source":"shutil.unpack_archive('/kaggle/input/cifar-10/test.7z','/kaggle/working/')","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:40:04.355722Z","iopub.execute_input":"2022-04-05T18:40:04.356196Z","iopub.status.idle":"2022-04-05T18:53:40.953765Z","shell.execute_reply.started":"2022-04-05T18:40:04.356160Z","shell.execute_reply":"2022-04-05T18:53:40.953011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This line of code extracts the CIFAR-10 test dataset from a 7z archive into the working directory for further use.","metadata":{}},{"cell_type":"code","source":"#with py7zr.SevenZipFile('/kaggle/input/cifar-10/test.7z', mode='r') as z:\n#    z.extractall()","metadata":{"execution":{"iopub.status.busy":"2022-03-24T18:22:15.484795Z","iopub.execute_input":"2022-03-24T18:22:15.485061Z","iopub.status.idle":"2022-03-24T18:22:15.488983Z","shell.execute_reply.started":"2022-03-24T18:22:15.485027Z","shell.execute_reply":"2022-03-24T18:22:15.488118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras_preprocessing.image import ImageDataGenerator\ndef append_ext(fn):\n    return fn+\".png\"\ntraindf=pd.read_csv(r'/kaggle/input/cifar-10/trainLabels.csv', dtype=str)\ntestdf=pd.read_csv(r\"/kaggle/input/cifar-10/sampleSubmission.csv\",dtype=str)\ntraindf[\"id\"]=traindf[\"id\"].apply(append_ext)\ntestdf[\"id\"]=testdf[\"id\"].apply(append_ext)\n","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:55:31.512439Z","iopub.execute_input":"2022-04-05T18:55:31.512894Z","iopub.status.idle":"2022-04-05T18:55:31.810093Z","shell.execute_reply.started":"2022-04-05T18:55:31.512856Z","shell.execute_reply":"2022-04-05T18:55:31.809343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code utilizes the Keras ImageDataGenerator and modifies file names. It reads CIFAR-10 dataset labels from CSV files. The `append_ext` function adds \".png\" extension to each file name. The train and test DataFrames are then updated with modified IDs for image file references.","metadata":{}},{"cell_type":"code","source":"datagen=ImageDataGenerator(rescale=1./255.,validation_split=0.2)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:55:34.849546Z","iopub.execute_input":"2022-04-05T18:55:34.849789Z","iopub.status.idle":"2022-04-05T18:55:34.853835Z","shell.execute_reply.started":"2022-04-05T18:55:34.849762Z","shell.execute_reply":"2022-04-05T18:55:34.852919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen=ImageDataGenerator(rescale=1./255.)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:55:36.326538Z","iopub.execute_input":"2022-04-05T18:55:36.327060Z","iopub.status.idle":"2022-04-05T18:55:36.330750Z","shell.execute_reply.started":"2022-04-05T18:55:36.327022Z","shell.execute_reply":"2022-04-05T18:55:36.329827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator=datagen.flow_from_dataframe(\n    dataframe=traindf,\n    directory=\"/kaggle/working/train/\",\n    x_col=\"id\",\n    y_col=\"label\",\n    subset=\"training\",\n    batch_size=128,\n    seed=42,\n    shuffle=True,\n    class_mode=\"categorical\",\n    target_size=(32,32))\n\nvalid_generator=datagen.flow_from_dataframe(\n    dataframe=traindf,\n    directory=\"/kaggle/working/train/\",\n    x_col=\"id\",\n    y_col=\"label\",\n    subset=\"validation\",\n    batch_size=128,\n    seed=42,\n    shuffle=True,\n    class_mode=\"categorical\",\n    target_size=(32,32))\n\ntest_generator=test_datagen.flow_from_dataframe(\n    dataframe=testdf,\n    directory=\"/kaggle/working/test/\",\n    x_col=\"id\",\n    y_col=None,\n    batch_size=32,\n    seed=42,\n    shuffle=False,\n    class_mode=None,\n    target_size=(32,32))","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:55:40.348673Z","iopub.execute_input":"2022-04-05T18:55:40.349202Z","iopub.status.idle":"2022-04-05T18:55:43.980677Z","shell.execute_reply.started":"2022-04-05T18:55:40.349163Z","shell.execute_reply":"2022-04-05T18:55:43.979986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code configures data generators for training, validation, and testing using the CIFAR-10 dataset. For training and validation, the `ImageDataGenerator` is set to rescale pixel values to the range [0, 1], with a validation split of 20%. The `train_generator` generates training batches from image files with labels from the train DataFrame. The `valid_generator` does the same for validation data. For testing, the `test_generator` generates batches without labels from image files in the test DataFrame. All generators use a batch size of 128 for training/validation and 32 for testing. Images are resized to 32x32 pixels. Data is read from respective directories, shuffled, and processed as categorical classes for training and validation, while testing generator preserves the image order. This setup prepares data for training and evaluating a neural network model on the CIFAR-10 dataset.","metadata":{}},{"cell_type":"code","source":"from keras.models import Sequential\n#Import from keras_preprocessing not from keras.preprocessing\nfrom keras_preprocessing.image import ImageDataGenerator\nfrom keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras import regularizers, optimizers\nimport pandas as pd\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:55:48.922191Z","iopub.execute_input":"2022-04-05T18:55:48.922682Z","iopub.status.idle":"2022-04-05T18:55:48.927511Z","shell.execute_reply.started":"2022-04-05T18:55:48.922643Z","shell.execute_reply":"2022-04-05T18:55:48.926523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = Sequential()\n# model.add(Conv2D(32, (3, 3), padding='same',input_shape=(32,32,3)))\n# model.add(Activation('relu'))\n# model.add(Conv2D(32, (3, 3)))\n# model.add(Activation('relu'))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n# model.add(Conv2D(64, (3, 3), padding='same'))\n# model.add(Activation('relu'))\n# model.add(Conv2D(64, (3, 3)))\n# model.add(Activation('relu'))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n# model.add(Flatten())\n# model.add(Dense(512))\n# model.add(Activation('relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(10, activation='softmax'))\n# model.compile(tf.keras.optimizers.Nadam(\n#     learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07),loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])\n\n\nmodel = Sequential()\nmodel.add(Conv2D(64, (5, 5), padding='same',input_shape=(32,32,3)))\nmodel.add(tf.keras.layers.LeakyReLU())\nmodel.add(tf.keras.layers.BatchNormalization())\n\nmodel.add(Conv2D(64, (5, 5)))\nmodel.add(tf.keras.layers.LeakyReLU())\nmodel.add(tf.keras.layers.BatchNormalization())\n\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, (5, 5), padding='same'))\nmodel.add(tf.keras.layers.LeakyReLU())\nmodel.add(tf.keras.layers.BatchNormalization())\n\nmodel.add(Conv2D(64, (5, 5)))\nmodel.add(tf.keras.layers.LeakyReLU())\nmodel.add(tf.keras.layers.BatchNormalization())\n\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten())\nmodel.add(Dense(512))\nmodel.add(tf.keras.layers.LeakyReLU())\nmodel.add(Dropout(0.5))\nmodel.add(Dense(10, activation='softmax'))\nmodel.compile(tf.keras.optimizers.Nadam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07),\n              loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:56:20.548541Z","iopub.execute_input":"2022-04-05T18:56:20.548802Z","iopub.status.idle":"2022-04-05T18:56:23.036780Z","shell.execute_reply.started":"2022-04-05T18:56:20.548774Z","shell.execute_reply":"2022-04-05T18:56:23.035018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code defines a Convolutional Neural Network (CNN) architecture using Keras. The model consists of multiple convolutional layers, activation functions, batch normalization, max-pooling, dropout, and fully connected layers. It's designed for image classification on the CIFAR-10 dataset.\n\nKey Layers:\n- Convolutional layers: Detect features using 64 filters with a 5x5 kernel size.\n- LeakyReLU activation: Introduces non-linearity and allows a small gradient for negative values.\n- BatchNormalization: Normalizes activations to improve training stability and speed.\n- MaxPooling2D: Reduces spatial dimensions for feature selection.\n- Dropout: Prevents overfitting by randomly dropping 25% of neurons during training.\n- Fully connected layers: Flatten features and apply dense connections with leaky ReLU activation.\n- Softmax activation: Final layer with 10 output nodes for class probabilities.\n\nThe model is compiled with the Nadam optimizer (a variant of Adam), categorical cross-entropy loss, and accuracy metric. It's ready for training on CIFAR-10 images. This architecture aims to learn relevant features and relationships to classify the images into their respective classes.","metadata":{}},{"cell_type":"code","source":"STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size\nSTEP_SIZE_TEST=test_generator.n//test_generator.batch_size\nmodel.fit_generator(generator=train_generator,\n                    steps_per_epoch=STEP_SIZE_TRAIN,\n                    validation_data=valid_generator,\n                    validation_steps=STEP_SIZE_VALID,\n                    epochs=30\n)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T18:56:30.641902Z","iopub.execute_input":"2022-04-05T18:56:30.642606Z","iopub.status.idle":"2022-04-05T19:02:45.477746Z","shell.execute_reply.started":"2022-04-05T18:56:30.642567Z","shell.execute_reply":"2022-04-05T19:02:45.476899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code trains the defined CNN model on the CIFAR-10 training data using a generator. It specifies the number of steps for training and validation, calculated based on the dataset size and batch size. The `fit_generator` function trains the model for 30 epochs using batches generated by the `train_generator` and evaluates it using batches from the `valid_generator`. This approach utilizes data augmentation, reduces overfitting, and improves generalization, enhancing the model's performance on the CIFAR-10 dataset.","metadata":{}},{"cell_type":"code","source":"filenames = test_generator.filenames\nnb_samples = len(filenames)\n\npredict = model.predict_generator(test_generator,nb_samples)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:04:10.831386Z","iopub.execute_input":"2022-04-05T19:04:10.832123Z","iopub.status.idle":"2022-04-05T19:05:38.678473Z","shell.execute_reply.started":"2022-04-05T19:04:10.832087Z","shell.execute_reply":"2022-04-05T19:05:38.677729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In this code, predictions are generated using the trained model on the CIFAR-10 test dataset. The list of filenames in the test generator and the total number of samples are retrieved. Then, the model's `predict_generator` method is used to generate predictions for all the test samples. The resulting `predict` array contains predicted class probabilities for each sample. This process allows the model to make predictions on the test dataset, which can be further analyzed or used for submission.","metadata":{}},{"cell_type":"code","source":"test_generator.reset()\npredictions_vecs = model.predict(test_generator)\n\npredictions_final = np.argmax(predictions_vecs, axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:05:38.680068Z","iopub.execute_input":"2022-04-05T19:05:38.680318Z","iopub.status.idle":"2022-04-05T19:07:03.532129Z","shell.execute_reply.started":"2022-04-05T19:05:38.680284Z","shell.execute_reply":"2022-04-05T19:07:03.531381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In this code, predictions are generated from the model using the CIFAR-10 test generator. The generator is first reset to ensure it starts from the beginning. Then, the model's `predict` function is used to generate prediction vectors for the test samples. Finally, the `argmax` function is applied along the second axis (axis=1) to determine the predicted class for each sample, resulting in the `predictions_final` array containing the predicted class labels.","metadata":{}},{"cell_type":"code","source":"predictions_final","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:07:03.533218Z","iopub.execute_input":"2022-04-05T19:07:03.533462Z","iopub.status.idle":"2022-04-05T19:07:03.538563Z","shell.execute_reply.started":"2022-04-05T19:07:03.533429Z","shell.execute_reply":"2022-04-05T19:07:03.537813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for fname in test_generator.filenames:\n    #filenames_wo_ext.append(int(fname.split(sep=\"/\")[1].split(sep=\".\")[0]) - 1)\n    print(fname)\n    break","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:07:03.540580Z","iopub.execute_input":"2022-04-05T19:07:03.540971Z","iopub.status.idle":"2022-04-05T19:07:03.552562Z","shell.execute_reply.started":"2022-04-05T19:07:03.540923Z","shell.execute_reply":"2022-04-05T19:07:03.551834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(type(train_generator.class_indices))\nprint(train_generator.class_indices)\n\nclasses = {value:key for (key,value) in train_generator.class_indices.items()}\nprint(classes)\n\npredicted_classes=np.empty(shape=300000,dtype=np.dtype('U20'))\n\nind=0\nfor i in predictions_final.tolist():\n    predicted_classes[ind]=classes[i]\n    ind=ind+1\n    \nfilenames_wo_ext = []\nfor fname in test_generator.filenames:\n    filenames_wo_ext.append(int(fname.split(sep=\".\")[0]) - 1)\n\npredicted_classes_final = np.empty(shape=300000,dtype=np.dtype('U20'))\npredicted_classes_final[filenames_wo_ext]=predicted_classes","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:07:03.553822Z","iopub.execute_input":"2022-04-05T19:07:03.554161Z","iopub.status.idle":"2022-04-05T19:07:03.970189Z","shell.execute_reply.started":"2022-04-05T19:07:03.554124Z","shell.execute_reply":"2022-04-05T19:07:03.969502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code maps and processes the predictions to make them more interpretable:\n\n1. It first prints and shows the class indices dictionary, indicating the mapping of classes to their respective numeric labels.\n2. The `classes` dictionary is created, reversing the class indices to map numeric labels back to their original class names.\n3. Predicted class labels are converted from numeric labels to class names using the `classes` dictionary and stored in the `predicted_classes` array.\n4. A list of image file names without extensions is created by extracting the image ID numbers from the filenames.\n5. The `predicted_classes` array is assigned to the corresponding positions in the `predicted_classes_final` array using the `filenames_wo_ext` list.\n\nThe final result, `predicted_classes_final`, contains the predicted class names for each test sample, making it easier to understand and interpret the model's predictions.","metadata":{}},{"cell_type":"code","source":"sub = pd.read_csv('/kaggle/input/cifar-10/sampleSubmission.csv',header='infer')\nsub.info()","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:09:53.261934Z","iopub.execute_input":"2022-04-05T19:09:53.262355Z","iopub.status.idle":"2022-04-05T19:09:53.424019Z","shell.execute_reply.started":"2022-04-05T19:09:53.262308Z","shell.execute_reply":"2022-04-05T19:09:53.423276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub['label'] = predicted_classes_final\nsub.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-04-05T19:09:55.718421Z","iopub.execute_input":"2022-04-05T19:09:55.718703Z","iopub.status.idle":"2022-04-05T19:09:56.230249Z","shell.execute_reply.started":"2022-04-05T19:09:55.718673Z","shell.execute_reply":"2022-04-05T19:09:56.229533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In this code, the predicted class labels are assigned to the 'label' column of a DataFrame named `sub`, which likely represents the submission format required by Kaggle. The DataFrame is then saved to a CSV file named 'submission.csv' without including the index column, as specified by `index=False`. This CSV file can be submitted to the Kaggle competition to evaluate the model's performance.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}