{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":30408,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Setup","metadata":{}},{"cell_type":"code","source":"# List contents of the working directory\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-28T12:58:50.609967Z","iopub.execute_input":"2023-12-28T12:58:50.610714Z","iopub.status.idle":"2023-12-28T12:58:50.644236Z","shell.execute_reply.started":"2023-12-28T12:58:50.610673Z","shell.execute_reply":"2023-12-28T12:58:50.643149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Python package to open .7z archives\n!pip install py7zr;","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:58:50.646620Z","iopub.execute_input":"2023-12-28T12:58:50.647338Z","iopub.status.idle":"2023-12-28T12:59:07.414529Z","shell.execute_reply.started":"2023-12-28T12:58:50.647290Z","shell.execute_reply":"2023-12-28T12:59:07.413434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import libraries\n\n# Loading and processing\nimport glob\nimport cv2\nimport py7zr\n\n# Data manipulation\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Tensorflow\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:59:07.416196Z","iopub.execute_input":"2023-12-28T12:59:07.416620Z","iopub.status.idle":"2023-12-28T12:59:15.478160Z","shell.execute_reply.started":"2023-12-28T12:59:07.416567Z","shell.execute_reply":"2023-12-28T12:59:15.477014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:59:15.479890Z","iopub.execute_input":"2023-12-28T12:59:15.481079Z","iopub.status.idle":"2023-12-28T12:59:16.490789Z","shell.execute_reply.started":"2023-12-28T12:59:15.481028Z","shell.execute_reply":"2023-12-28T12:59:16.489543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Look for GPU\ndevice_name = tf.test.gpu_device_name()\nif device_name != '/device:GPU:0':\n    print('GPU device not found')\nprint('Found GPU at: {}'.format(device_name))","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:59:16.493886Z","iopub.execute_input":"2023-12-28T12:59:16.494201Z","iopub.status.idle":"2023-12-28T12:59:18.742760Z","shell.execute_reply.started":"2023-12-28T12:59:16.494169Z","shell.execute_reply":"2023-12-28T12:59:18.741635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading the data","metadata":{}},{"cell_type":"code","source":"# Class labels\nCLASS_NAMES = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck']","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:59:18.744371Z","iopub.execute_input":"2023-12-28T12:59:18.744717Z","iopub.status.idle":"2023-12-28T12:59:18.755479Z","shell.execute_reply.started":"2023-12-28T12:59:18.744680Z","shell.execute_reply":"2023-12-28T12:59:18.754503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Open training archive file\n\nif not len(glob.glob('/kaggle/working/train/*.png')):\n    with py7zr.SevenZipFile('/kaggle/input/cifar-10/train.7z', mode='r') as z:\n        z.extractall()","metadata":{"execution":{"iopub.status.busy":"2023-12-28T12:59:18.756781Z","iopub.execute_input":"2023-12-28T12:59:18.757096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert the filepath to an integer image ID\ndef filename_to_id(filename):\n    return int(filename.split('/')[-1].split('.')[0])\n\n# Load all of the images into an array, also return the image IDs\ndef load_imgs_and_ids(img_directory_path):\n    image_filenames = glob.glob(img_directory_path + '/*.png')\n    list_of_images = []\n    image_ids = []\n    for f in image_filenames:\n        image_id = filename_to_id(f) # E.G. '/kaggle/working/train/44240.png' -> 44240\n        image_ids.append(image_id)\n        data_array = cv2.imread(f)\n        list_of_images.append(data_array)\n\n    X = np.array(list_of_images)\n    \n    return X, image_ids\n    \nX_train, train_img_ids = load_imgs_and_ids('/kaggle/working/train')\n\n# Read the labels from the CSV files and convert the array of IDs into a 0-9 code\ntrain_labels_df = pd.read_csv('/kaggle/input/cifar-10/trainLabels.csv')\nimg_codes = [CLASS_NAMES.index(train_labels_df.loc[img_id-1]['label']) for img_id in train_img_ids]\ny_train = np.array(img_codes)\n\nX_train.shape, y_train.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Alternatively, could use data from Tensorflow\n\"\"\"\nfrom tensorflow.keras.datasets import cifar10\n\n(X_train,y_train),(some_more_images,some_more_labels) = cifar10.load_data()\nprint(X_train.shape, y_train.shape)\n\ny_train = y_train.reshape((50000,))\n\"\"\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# RGB pixel values lie on a [0,...,255] scale. We rescale the channels to have channel intensities lie \n# from 0 to 1 inclusive\n\nX_train = X_train / 255.0","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualization","metadata":{}},{"cell_type":"code","source":"# To get a sense of the data we work with\n\nplt.rcParams[\"figure.figsize\"] = (10,10)\nfig,axes = plt.subplots(10,10)\nfor i,ax in enumerate(axes.flatten()):\n  ax.imshow(X_train[i])\n  ax.set_title(f'{CLASS_NAMES[y_train[i]]}')\n  ax.set_xticks([])\n  ax.set_yticks([])\nfig.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convolutional Neural Network Architecture","metadata":{}},{"cell_type":"code","source":"# CNN model, with 6 convolutional layers, 3 pooling layers, and 3 dense layers. Softmax output layer.\nmodel = models.Sequential()\n\nmodel.add(layers.Conv2D(64, (5,5), padding='same', activation='relu', input_shape=(32,32,3)))\nmodel.add(layers.Conv2D(128, (3,3), padding='same', activation='relu'))\nmodel.add(layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)))\n\nmodel.add(layers.Conv2D(128, (3,3), padding='same', activation='relu'))\nmodel.add(layers.Conv2D(128, (3,3), padding='same', activation='relu'))\nmodel.add(layers.MaxPooling2D(pool_size=(2,2)))\n\nmodel.add(layers.Conv2D(128, (3,3), padding='same', activation='relu'))\nmodel.add(layers.Conv2D(128, (3,3), padding='same', activation='relu'))\nmodel.add(layers.MaxPooling2D(pool_size=(2,2)))\n\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(128, activation='relu'))\nmodel.add(layers.Dense(64, activation='relu'))\nmodel.add(layers.Dense(10, activation='softmax'))\n\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer='adam',\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(),\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augmenting the training data and training the model","metadata":{}},{"cell_type":"code","source":"# We augment the training data within the mini-batches to try to reduce generalization error\ndatagen = ImageDataGenerator(\n    horizontal_flip=True,\n    channel_shift_range=0.05,\n    rotation_range=10,\n    validation_split=0.15\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# An example transformation\n\nimg = X_train[4]\n\nfig, ax = plt.subplots(1,2)\nax[0].imshow(img)\nax[0].set_title(\"Original image\")\nax[1].imshow(datagen.apply_transform(img,{'theta':-10,'channel_shift_intensity':0.05,'flip_horizontal':True}))\nax[1].set_title(\"Example transformation\")\n\nfor i in range(2):\n  ax[i].set_xticks([])\n  ax[i].set_yticks([])\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model, including an early stopping if we can't reduce the loss further\n\nearly_stopping = keras.callbacks.EarlyStopping(monitor='loss',patience=10)\n\ntraining_flow = datagen.flow(X_train, y_train, subset='training')\nvalidation_flow = datagen.flow(X_train, y_train, subset='validation', shuffle=False)\n\nhistory = model.fit(training_flow,validation_split=0.1,\n                    verbose=1,\n                    validation_data=validation_flow,\n                    callbacks=[early_stopping],\n                    epochs=70)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model evaluation","metadata":{}},{"cell_type":"code","source":"# Plot the evolution of training/validation error and accuracy\nevaluation = model.evaluate(X_train, y_train)\nprint(f'Test Accuracy : {evaluation[1] * 100:.2f}%')\n\ntrain_metrics = history.history\n\nfig, ax = plt.subplots(1,2)\nax[0].plot(train_metrics['loss'])\nax[0].plot(train_metrics['val_loss'])\nax[0].legend(['train','val'], loc='upper right')\nax[0].set_xlabel(\"Epoch\")\nax[0].set_ylabel(\"Loss\")\nax[0].set_title(\"Loss over the training epochs\")\n\nax[1].plot(train_metrics['accuracy'])\nax[1].plot(train_metrics['val_accuracy'])\nax[1].legend(['train','val'], loc='upper right')\nax[1].set_xlabel(\"Epoch\")\nax[1].set_ylabel(\"Accuracy\")\nax[1].set_title(\"Accuracy over the training epochs\")\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example predictions\n\nsample_set = X_train[100:125]\n\nsample_predictions = np.argmax(model.predict(sample_set),axis=1)\n\nfig,axes = plt.subplots(5,5)\nfor i,ax in enumerate(axes.flatten()):\n  ax.imshow(sample_set[i])\n  ax.set_title(f'{CLASS_NAMES[sample_predictions[i]]}')\n  ax.set_xticks([])\n  ax.set_yticks([])\nfig.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}