{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":31234,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## __Create Computer Vision Algorithms__\nDawud Ujamaa  \nJanuary 11, 2026","metadata":{}},{"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 warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom PIL import Image\n\nfrom sklearn import metrics\nfrom sklearn.metrics import confusion_matrix, classification_report \nfrom sklearn.metrics import roc_curve, auc, RocCurveDisplay\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import label_binarize, MinMaxScaler\nfrom sklearn.multiclass import OneVsRestClassifier\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras import datasets, layers, models \nfrom tensorflow.keras.layers import Dense \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\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\n\n# Needed for reproducibility\nimport random\nseed = 42 # Set Python's hash seed\nos.environ['PYTHONHASHSEED'] = str(seed)\n# Set random seeds for reproducibility\ntf.random.set_seed(seed)  # For TensorFlow operations\nnp.random.seed(seed)      # For NumPy operations\nrandom.seed(seed)         # For Python's random module","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:28:08.403736Z","iopub.execute_input":"2025-12-31T16:28:08.404077Z","iopub.status.idle":"2025-12-31T16:28:33.062148Z","shell.execute_reply.started":"2025-12-31T16:28:08.404037Z","shell.execute_reply":"2025-12-31T16:28:33.060799Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __1. Load the dataset:__ ","metadata":{}},{"cell_type":"code","source":"# load the dataset containing lables and include a column for filename and numeric label\nlabels_df = pd.read_csv('../input/cifar-10/trainLabels.csv')\nlabels_df['filename'] = labels_df['id'].astype(str) + '.png'\n\nclass_vals = {'airplane':0, 'automobile':1, 'bird':2, 'cat':3, 'deer':4, 'dog':5, 'frog':6, 'horse':7, 'ship':8, 'truck':9}\nlabels_df['label_idx'] = labels_df['label'].map(class_vals)\n\nlabels_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:29:08.579569Z","iopub.execute_input":"2025-12-31T16:29:08.579888Z","iopub.status.idle":"2025-12-31T16:29:08.674312Z","shell.execute_reply.started":"2025-12-31T16:29:08.579859Z","shell.execute_reply":"2025-12-31T16:29:08.673192Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Unpack image files\n!7z x /kaggle/input/cifar-10/train.7z -o/kaggle/working/train -bso0 -bsp0 -mtc=off","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:29:41.127226Z","iopub.execute_input":"2025-12-31T16:29:41.127565Z","iopub.status.idle":"2025-12-31T16:37:07.285228Z","shell.execute_reply.started":"2025-12-31T16:29:41.127538Z","shell.execute_reply":"2025-12-31T16:37:07.282983Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TRAIN_DIR = r\"../working/train/train\"\n\n# build dataset from image files\nimages = []\nlabels = []\nimg_size=(32, 32) # CIFAR-10 image size\n\nfor _, row in labels_df.iterrows():\n    img_path = os.path.join(TRAIN_DIR, row[\"filename\"])\n\n    # Load image\n    img = Image.open(img_path).convert(\"RGB\")\n    img = img.resize(img_size)\n\n    images.append(np.array(img))\n    labels.append(row[\"label_idx\"])\n\nX_TRAIN = np.array(images, dtype=np.float32)\nY_TRAIN = np.array(labels, dtype=np.int64)\n\nx_train, x_test0, y_train, y_test = train_test_split(X_TRAIN, Y_TRAIN, test_size=0.2, random_state=42, stratify=Y_TRAIN)\n\ny_train = y_train.reshape(-1, 1)\ny_test = y_test.reshape(-1, 1)\n\n# Check shapes\nprint(x_train.shape, y_train.shape)\nprint(x_test0.shape, y_test.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:37:38.158401Z","iopub.execute_input":"2025-12-31T16:37:38.158882Z","iopub.status.idle":"2025-12-31T16:37:56.518029Z","shell.execute_reply.started":"2025-12-31T16:37:38.158840Z","shell.execute_reply":"2025-12-31T16:37:56.516967Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CIFAR-10 class names\nclass_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n\nplt.figure(figsize=(12, 2))\n\nfor i in range(20):\n    plt.subplot(2, 10, i + 1)\n    plt.imshow(x_train[i] / 255.0)\n    plt.title(class_names[y_train[i][0]])\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:38:42.986167Z","iopub.execute_input":"2025-12-31T16:38:42.986569Z","iopub.status.idle":"2025-12-31T16:38:43.786585Z","shell.execute_reply.started":"2025-12-31T16:38:42.986537Z","shell.execute_reply":"2025-12-31T16:38:43.785464Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __2. Normalize and reshape the data to fit the input requirements:__","metadata":{}},{"cell_type":"code","source":"# Normalize the pixel values to range between 0 and 1 \nx_train = x_train / 255.0\nx_test = x_test0 / 255.0\n\n# Add a channel dimension (required for CNN) \nx_train = np.expand_dims(x_train, axis=-1) \nx_test = np.expand_dims(x_test, axis=-1) \n\n# Split training data into 80% training and 20% validation \ntrain_images, val_images, train_labels, val_labels = train_test_split(x_train, y_train, test_size=0.2, random_state=42) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-31T16:38:53.381724Z","iopub.execute_input":"2025-12-31T16:38:53.382074Z","iopub.status.idle":"2025-12-31T16:38:53.850159Z","shell.execute_reply.started":"2025-12-31T16:38:53.382043Z","shell.execute_reply":"2025-12-31T16:38:53.849233Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __3. Build an appropriate CNN model.__","metadata":{}},{"cell_type":"code","source":"# Define a CNN model \nmodel = models.Sequential([\n    # Data augmentation\n    layers.RandomFlip(\"horizontal\", input_shape=(32, 32, 3)),\n    layers.RandomRotation(0.05),\n    layers.RandomZoom(0.05),\n\n    # low-level convolutional layers\n    layers.Conv2D(32, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),\n    layers.Conv2D(32, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Dropout(0.15),\n\n    # mid-level convolutional layers\n    layers.Conv2D(64, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),\n    layers.Conv2D(64, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Dropout(0.15),\n\n    # high-level convolutional layers\n    layers.Conv2D(128, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),\n    layers.Conv2D(128, (3, 3), padding='same'),\n    layers.BatchNormalization(),\n    layers.Activation('relu'),    \n    layers.MaxPooling2D((2, 2)),\n    layers.Dropout(0.15),\n\n    # Classification and output     \n    layers.Flatten(),\n    layers.Dense(256, activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(0.5),\n    layers.Dense(10, activation='softmax')\n])\n\n# Compile the model\noptimizer = tf.keras.optimizers.Adam(learning_rate=0.001)\n\nmodel.compile(optimizer=optimizer,\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\n\nmodel.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __4. Train the model and monitor the training process (loss and accuracy)__","metadata":{}},{"cell_type":"code","source":"# Train the model \nhistory = model.fit(train_images, train_labels, epochs=45, validation_data=(val_images, val_labels), verbose=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axs = plt.subplots(1,2,figsize=(12,4)) \n\n# loss\naxs[0].plot(history.history['loss'], label='Training Loss') \naxs[0].plot(history.history['val_loss'], label='Validation Loss') \naxs[0].set_title('Model Loss')\naxs[0].set_ylabel('Loss') \naxs[0].set_xlabel('Epoch')\naxs[0].legend(['train', 'validate'], loc='upper left')\n\n# accuracy\naxs[1].plot(history.history['accuracy'], label='Training Accuracy') \naxs[1].plot(history.history['val_accuracy'], label='Validation Accuracy') \naxs[1].set_title('Model Accuracy')\naxs[1].set_ylabel('Accuracy') \naxs[1].set_xlabel('Epoch')\naxs[1].legend(['train', 'validate'], loc='upper left')\n\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __5. Evaluate your model on the test set and record your accuracy.__","metadata":{}},{"cell_type":"code","source":"# Evaluate the model on the test set \ntest_loss, test_acc = model.evaluate(x_test, y_test, verbose=2) \nprint(f'\\nTest accuracy: {test_acc:.2f}')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Classification Reports \n\n# Predictions\ny_pred_train = model.predict(x_train).argmax(axis=1)\ny_pred_test = model.predict(x_test).argmax(axis=1)\n\n# generate Classification report on training and test set\nprint( 'Classification Report on Training set')\nprint(classification_report(y_train,y_pred_train, digits=4, target_names=class_names))\n\nprint( 'Classification Report on Test set')\nprint(classification_report(y_test,y_pred_test, digits=4, target_names=class_names))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __6. Visualize the results and predictions of the model.__","metadata":{}},{"cell_type":"code","source":"# Confusion matrix on Training set\n\nconf_matrix_train = metrics.confusion_matrix(y_train, y_pred_train)\n\nplt.figure(figsize=(8, 6)) \nsns.heatmap(conf_matrix_train, annot=True, fmt='d', cmap='Blues', xticklabels=class_names, yticklabels=class_names) \nplt.xlabel('Predicted Label') \nplt.ylabel('True Label') \nplt.title('Confusion Matrix for CIFAR-10 Classification on Training Set') \nplt.show() ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Confusion matrix on Test set\n\nconf_matrix_test = metrics.confusion_matrix(y_test, y_pred_test)\n\nplt.figure(figsize=(8, 6)) \nsns.heatmap(conf_matrix_test, annot=True, fmt='d', cmap='Blues', xticklabels=class_names, yticklabels=class_names) \nplt.xlabel('Predicted Label') \nplt.ylabel('True Label') \nplt.title('Confusion Matrix for CIFAR-10 Classification on test set.') \nplt.show() ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# First 30 images in CIFAR-10 test dataset with predicted labels\nplt.figure(figsize=(12, 3))\n\nfor i in range(30):\n    plt.subplot(3, 10, i + 1)\n    plt.imshow(x_test0[i] / 255.0)\n    plt.title(f\"Actual: {class_names[y_test[i][0]]}\\nPred: {class_names[y_pred_test[i]]}\", fontsize=8)\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### __7. Submit predictions to Kaggle.__","metadata":{}},{"cell_type":"code","source":"# load test data\n!7z x /kaggle/input/cifar-10/test.7z -o/kaggle/working/test -bso0 -bsp0 -mtc=off","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TEST_DIR = r\"../working/test/test\"\ntest_files = os.listdir(TEST_DIR)\ndf_test_files = pd.DataFrame(test_files, columns=[\"filename\"])\ndf_test_files['id'] = df_test_files[\"filename\"].str.replace(\".png\", \"\")\ndf_test_files['id'] = df_test_files['id'].astype(int)\n\nid_test = df_test_files['id']\n\ndf_test_files","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_images = []\n\nfor _, row in df_test_files.iterrows():\n    img_path = os.path.join(TEST_DIR, row[\"filename\"])\n\n    # Load image\n    img = Image.open(img_path).convert(\"RGB\")\n    img = img.resize(img_size)\n\n    test_images.append(np.array(img))\n\nX_TEST0 = np.array(test_images, dtype=np.float32)\n\n# Check shapes\nprint(X_TEST0.shape)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Normalize the pixel values to range between 0 and 1 \nX_TEST = X_TEST0 / 255.0\nX_TRAIN = X_TRAIN / 255.0\n\n# Add a channel dimension (required for CNN) \nX_TEST = np.expand_dims(X_TEST, axis=-1) \nX_TRAIN = np.expand_dims(X_TRAIN, axis=-1) \n\nY_TRAIN = Y_TRAIN.reshape(-1, 1)\n\n# Check shapes\nprint(X_TRAIN.shape, Y_TRAIN.shape)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train model on full training data\nhistory = model.fit(X_TRAIN, Y_TRAIN, epochs=45, verbose=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# make predictions on competition test dataset\nY_TEST_PRED = model.predict(X_TEST).argmax(axis=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame(id_test)\nsubmission['labelnum'] = Y_TEST_PRED\n\n# add a column with numeric values for class\nclass_vals = {0:'airplane', 1:'automobile', 2:'bird', 3:'cat', 4:'deer', 5:'dog', 6:'frog', 7:'horse', 8:'ship', 9:'truck'}\nsubmission['label']=submission['labelnum'].map(class_vals)\nsubmission.drop('labelnum', axis=1, inplace=True)\nsubmission.sort_values(by='id', inplace=True)\nsubmission.to_csv(r'./submission.csv', index = False)\nsubmission","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# First 30 images in CIFAR-10 TEST Competition dataset with predicted labels\nplt.figure(figsize=(12, 3))\n\nfor i in range(30):\n    plt.subplot(3, 10, i + 1)\n    plt.imshow(X_TEST0[i] / 255.0)\n    plt.title(class_names[Y_TEST_PRED[i]])\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# One-vs-Rest ROC curve\n\n# Get softmax predictions\ny_pred_probs = model.predict(x_test)\n\n# Binarize the true labels\nnum_classes = len(np.unique(y_test))\ny_test_bin = label_binarize(y_test, classes=list(range(num_classes)))\n\n# Compute ROC and AUC for each class\nfpr = {}   # false positive rate\ntpr = {}   # true positive rate\nroc_auc = {}\n\nfor i in range(num_classes):\n    fpr[i], tpr[i], _ = roc_curve(y_test_bin[:, i], y_pred_probs[:, i])\n    roc_auc[i] = auc(fpr[i], tpr[i])\n\n# Compute micro-average ROC curve\nfpr[\"micro\"], tpr[\"micro\"], _ = roc_curve(\n    y_test_bin.ravel(), \n    y_pred_probs.ravel()\n)\nroc_auc[\"micro\"] = auc(fpr[\"micro\"], tpr[\"micro\"])\n\n# Compute macro-average ROC curve\n# Aggregate all FPR points\nall_fpr = np.unique(np.concatenate([fpr[i] for i in range(num_classes)]))\n\n# Interpolate TPR for each class at these FPR points\nmean_tpr = np.zeros_like(all_fpr)\nfor i in range(num_classes):\n    mean_tpr += np.interp(all_fpr, fpr[i], tpr[i])\n\nmean_tpr /= num_classes\n\nfpr[\"macro\"] = all_fpr\ntpr[\"macro\"] = mean_tpr\nroc_auc[\"macro\"] = auc(fpr[\"macro\"], tpr[\"macro\"])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot the One-vs-Rest ROC curves\n\nplt.figure(figsize=(10, 5))\n\n# Plot for each class\nfor i in range(num_classes):\n    plt.plot(fpr[i], tpr[i], linewidth=2,\n             label=f\"Class: Rating: {class_names[i]} (AUC = {roc_auc[i]:.3f})\")\n\n# Micro & Macro\nplt.plot(fpr[\"micro\"], tpr[\"micro\"],\n         linestyle='--', linewidth=2,\n         label=f\"micro-average (AUC = {roc_auc['micro']:.3f})\")\n\nplt.plot(fpr[\"macro\"], tpr[\"macro\"],\n         linestyle='--', linewidth=2,\n         label=f\"macro-average (AUC = {roc_auc['macro']:.3f})\")\n\n# Diagonal\nplt.plot([0, 1], [0, 1], 'k--')\n\nplt.xlabel(\"False Positive Rate\")\nplt.ylabel(\"True Positive Rate\")\nplt.title(\"Multi-Class ROC Curve (One-vs-Rest)\")\nplt.legend(loc=\"lower right\")\nplt.grid(True)\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}