{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# CELL 1: Check CIFAR-10 competition files\n\nimport os\n\nprint(\"Available CIFAR-10 files:\\n\")\n\nfor dirname, _, filenames in os.walk(\"/kaggle/input\"):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T13:54:31.327898Z","iopub.execute_input":"2026-09-23T13:54:31.328149Z","iopub.status.idle":"2026-09-23T13:54:31.338547Z","shell.execute_reply.started":"2026-09-23T13:54:31.328125Z","shell.execute_reply":"2026-09-23T13:54:31.337594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 2: Inspect Kaggle labels and submission format\n\nimport pandas as pd\n\nlabels_path = \"/kaggle/input/competitions/cifar-10/trainLabels.csv\"\nsubmission_path = \"/kaggle/input/competitions/cifar-10/sampleSubmission.csv\"\n\ntrain_labels = pd.read_csv(labels_path)\nsample_submission = pd.read_csv(submission_path)\n\nprint(\"Training labels shape:\", train_labels.shape)\nprint(\"\\nFirst 10 training labels:\")\nprint(train_labels.head(10))\n\nprint(\"\\nClass names:\")\nprint(sorted(train_labels[\"label\"].unique()))\n\nprint(\"\\nSample submission shape:\", sample_submission.shape)\nprint(\"\\nFirst 10 rows of sample submission:\")\nprint(sample_submission.head(10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T13:55:21.466908Z","iopub.execute_input":"2026-09-23T13:55:21.467653Z","iopub.status.idle":"2026-09-23T13:55:22.179164Z","shell.execute_reply.started":"2026-09-23T13:55:21.467621Z","shell.execute_reply":"2026-09-23T13:55:22.178267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 3: Load official CIFAR-10 data from Keras\n\nimport tensorflow as tf\nfrom tensorflow.keras.datasets import cifar10\n\n(X_train, y_train), (X_test_official, y_test_official) = cifar10.load_data()\n\nprint(\"X_train shape:\", X_train.shape)\nprint(\"y_train shape:\", y_train.shape)\n\nprint(\"Official X_test shape:\", X_test_official.shape)\nprint(\"Official y_test shape:\", y_test_official.shape)\n\nprint(\"Training pixel range:\", X_train.min(), \"to\", X_train.max())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T13:56:52.244749Z","iopub.execute_input":"2026-09-23T13:56:52.245202Z","iopub.status.idle":"2026-09-23T14:29:50.156858Z","shell.execute_reply.started":"2026-09-23T13:56:52.245172Z","shell.execute_reply":"2026-09-23T14:29:50.156061Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 4: Visualize CIFAR-10 training images\n\nimport matplotlib.pyplot as plt\n\nclass_names = [\n    \"airplane\", \"automobile\", \"bird\", \"cat\", \"deer\",\n    \"dog\", \"frog\", \"horse\", \"ship\", \"truck\"\n]\n\nplt.figure(figsize=(10, 5))\n\nfor i in range(10):\n    plt.subplot(2, 5, i + 1)\n    plt.imshow(X_train[i])\n    plt.title(class_names[int(y_train[i][0])])\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T14:30:32.99541Z","iopub.execute_input":"2026-09-23T14:30:32.996232Z","iopub.status.idle":"2026-09-23T14:30:33.475049Z","shell.execute_reply.started":"2026-09-23T14:30:32.996201Z","shell.execute_reply":"2026-09-23T14:30:33.474286Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 5: Normalize data and create training/validation split\n\nfrom sklearn.model_selection import train_test_split\n\n# Convert pixel values from 0-255 to 0-1\nX_train_norm = X_train.astype(\"float32\") / 255.0\nX_test_official_norm = X_test_official.astype(\"float32\") / 255.0\n\n# Flatten labels from (N, 1) to (N,)\ny_train_flat = y_train.reshape(-1)\ny_test_official_flat = y_test_official.reshape(-1)\n\n# Split the 50,000 training images:\n# 45,000 for training and 5,000 for validation\nX_train_final, X_val, y_train_final, y_val = train_test_split(\n    X_train_norm,\n    y_train_flat,\n    test_size=0.10,\n    random_state=42,\n    stratify=y_train_flat\n)\n\nprint(\"Training set:\", X_train_final.shape, y_train_final.shape)\nprint(\"Validation set:\", X_val.shape, y_val.shape)\nprint(\"Official test set:\", X_test_official_norm.shape, y_test_official_flat.shape)\n\nprint(\"Normalized pixel range:\",\n      X_train_final.min(), \"to\", X_train_final.max())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T14:31:23.297139Z","iopub.execute_input":"2026-09-23T14:31:23.297599Z","iopub.status.idle":"2026-09-23T14:31:24.186277Z","shell.execute_reply.started":"2026-09-23T14:31:23.297568Z","shell.execute_reply":"2026-09-23T14:31:24.185578Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 6: Build CNN from randomly initialized weights\n\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.layers import (\n    Input,\n    Conv2D,\n    BatchNormalization,\n    ReLU,\n    MaxPooling2D,\n    Dropout,\n    GlobalAveragePooling2D,\n    Dense,\n    RandomFlip,\n    RandomTranslation\n)\n\n# Data augmentation is applied only during training\ndata_augmentation = Sequential([\n    RandomFlip(\"horizontal\"),\n    RandomTranslation(height_factor=0.1, width_factor=0.1)\n], name=\"data_augmentation\")\n\n\nmodel = Sequential([\n    Input(shape=(32, 32, 3)),\n\n    # Data augmentation\n    data_augmentation,\n\n    # Block 1\n    Conv2D(64, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    Conv2D(64, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    MaxPooling2D((2, 2)),\n    Dropout(0.20),\n\n    # Block 2\n    Conv2D(128, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    Conv2D(128, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    MaxPooling2D((2, 2)),\n    Dropout(0.30),\n\n    # Block 3\n    Conv2D(256, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    Conv2D(256, (3, 3), padding=\"same\",\n           use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n\n    MaxPooling2D((2, 2)),\n    Dropout(0.40),\n\n    # Classification head\n    GlobalAveragePooling2D(),\n\n    Dense(256, use_bias=False, kernel_initializer=\"he_normal\"),\n    BatchNormalization(),\n    ReLU(),\n    Dropout(0.40),\n\n    Dense(10, activation=\"softmax\")\n])\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T14:37:22.609267Z","iopub.execute_input":"2026-09-23T14:37:22.610036Z","iopub.status.idle":"2026-09-23T14:37:22.768809Z","shell.execute_reply.started":"2026-09-23T14:37:22.61001Z","shell.execute_reply":"2026-09-23T14:37:22.768151Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 7: Compile CNN and prepare training callbacks\n\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import (\n    ReduceLROnPlateau,\n    EarlyStopping,\n    ModelCheckpoint\n)\n\n# Compile the model\nmodel.compile(\n    optimizer=Adam(learning_rate=0.001),\n    loss=\"sparse_categorical_crossentropy\",\n    metrics=[\"accuracy\"]\n)\n\n# Reduce learning rate if validation accuracy stops improving\nreduce_lr = ReduceLROnPlateau(\n    monitor=\"val_accuracy\",\n    factor=0.5,\n    patience=5,\n    min_lr=1e-6,\n    verbose=1\n)\n\n# Stop training if validation accuracy stops improving for a long time\nearly_stop = EarlyStopping(\n    monitor=\"val_accuracy\",\n    patience=15,\n    restore_best_weights=True,\n    verbose=1\n)\n\n# Save the best model\ncheckpoint = ModelCheckpoint(\n    \"/kaggle/working/best_cifar10_model.keras\",\n    monitor=\"val_accuracy\",\n    save_best_only=True,\n    verbose=1\n)\n\nprint(\"Model compiled successfully.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T14:37:28.144887Z","iopub.execute_input":"2026-09-23T14:37:28.145662Z","iopub.status.idle":"2026-09-23T14:37:28.157336Z","shell.execute_reply.started":"2026-09-23T14:37:28.145632Z","shell.execute_reply":"2026-09-23T14:37:28.156451Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 8: Train the CNN\n\nhistory = model.fit(\n    X_train_final,\n    y_train_final,\n    validation_data=(X_val, y_val),\n    epochs=100,\n    batch_size=128,\n    callbacks=[\n        reduce_lr,\n        early_stop,\n        checkpoint\n    ],\n    verbose=1\n)\n\nprint(\"Training completed successfully.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T14:37:31.542344Z","iopub.execute_input":"2026-09-23T14:37:31.543023Z","iopub.status.idle":"2026-09-23T15:04:15.27396Z","shell.execute_reply.started":"2026-09-23T14:37:31.54299Z","shell.execute_reply":"2026-09-23T15:04:15.273159Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 9: Evaluate the best model on the official CIFAR-10 test set\n\nimport tensorflow as tf\n\n# Load the best saved model\nbest_model = tf.keras.models.load_model(\n    \"/kaggle/working/best_cifar10_model.keras\"\n)\n\n# Evaluate on the untouched official test set\ntest_loss, test_accuracy = best_model.evaluate(\n    X_test_official_norm,\n    y_test_official_flat,\n    verbose=1\n)\n\nprint(\"\\nOfficial CIFAR-10 Test Loss:\", test_loss)\nprint(\"Official CIFAR-10 Test Accuracy:\", test_accuracy)\nprint(f\"Official Test Accuracy Percentage: {test_accuracy * 100:.2f}%\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T15:15:40.232953Z","iopub.execute_input":"2026-09-23T15:15:40.233747Z","iopub.status.idle":"2026-09-23T15:15:43.7327Z","shell.execute_reply.started":"2026-09-23T15:15:40.233695Z","shell.execute_reply":"2026-09-23T15:15:43.731861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 10: Extract Kaggle competition test images\n\nimport os\nimport subprocess\n\ntest_archive = \"/kaggle/input/competitions/cifar-10/test.7z\"\ntest_dir = \"/kaggle/working/test\"\n\nos.makedirs(test_dir, exist_ok=True)\n\nsubprocess.run(\n    [\"7z\", \"x\", \"-y\", test_archive, f\"-o{test_dir}\"],\n    check=True\n)\n\nprint(\"Test images extracted successfully.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T15:16:45.371673Z","iopub.execute_input":"2026-09-23T15:16:45.372403Z","iopub.status.idle":"2026-09-23T19:24:27.988783Z","shell.execute_reply.started":"2026-09-23T15:16:45.372373Z","shell.execute_reply":"2026-09-23T19:24:27.987897Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 11: Predict Kaggle test images and create submission.csv\n\nimport os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n\n# -------------------------------------------------\n# 1. Load the best trained model\n# -------------------------------------------------\nbest_model = tf.keras.models.load_model(\n    \"/kaggle/working/best_cifar10_model.keras\"\n)\n\n# CIFAR-10 class names in the correct order\nclass_names = np.array([\n    \"airplane\",\n    \"automobile\",\n    \"bird\",\n    \"cat\",\n    \"deer\",\n    \"dog\",\n    \"frog\",\n    \"horse\",\n    \"ship\",\n    \"truck\"\n])\n\n# -------------------------------------------------\n# 2. Read Kaggle's required submission order\n# -------------------------------------------------\nsample = pd.read_csv(\n    \"/kaggle/input/competitions/cifar-10/sampleSubmission.csv\"\n)\n\nprint(\"Number of Kaggle test images:\", len(sample))\n\n# Build image paths in EXACT Kaggle ID order\nimage_paths = [\n    f\"/kaggle/working/test/test/{image_id}.png\"\n    for image_id in sample[\"id\"]\n]\n\nprint(\"First image:\", image_paths[0])\nprint(\"Last image:\", image_paths[-1])\n\n# -------------------------------------------------\n# 3. Create fast TensorFlow input pipeline\n# -------------------------------------------------\ndef load_image(path):\n    image = tf.io.read_file(path)\n    image = tf.image.decode_png(image, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n\ndataset = tf.data.Dataset.from_tensor_slices(image_paths)\n\ndataset = dataset.map(\n    load_image,\n    num_parallel_calls=tf.data.AUTOTUNE\n)\n\ndataset = dataset.batch(1024)\n\ndataset = dataset.prefetch(tf.data.AUTOTUNE)\n\n# -------------------------------------------------\n# 4. Predict all 300,000 images\n# -------------------------------------------------\nprint(\"\\nStarting prediction...\")\n\nprobabilities = best_model.predict(\n    dataset,\n    verbose=1\n)\n\npredicted_numbers = np.argmax(\n    probabilities,\n    axis=1\n)\n\npredicted_labels = class_names[\n    predicted_numbers\n]\n\n# -------------------------------------------------\n# 5. Create Kaggle submission\n# -------------------------------------------------\nsubmission = pd.DataFrame({\n    \"id\": sample[\"id\"],\n    \"label\": predicted_labels\n})\n\nsubmission_path = \"/kaggle/working/submission.csv\"\n\nsubmission.to_csv(\n    submission_path,\n    index=False\n)\n\n# -------------------------------------------------\n# 6. Final checks\n# -------------------------------------------------\nprint(\"\\nSubmission shape:\", submission.shape)\nprint(\"\\nFirst rows:\")\nprint(submission.head())\n\nprint(\"\\nLast rows:\")\nprint(submission.tail())\n\nprint(\"\\nMissing labels:\", submission[\"label\"].isna().sum())\n\nprint(\"\\nSUBMISSION READY ✅\")\nprint(\"Saved at:\", submission_path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-23T19:25:58.905762Z","iopub.execute_input":"2026-09-23T19:25:58.90622Z","iopub.status.idle":"2026-09-23T19:26:33.78302Z","shell.execute_reply.started":"2026-09-23T19:25:58.906192Z","shell.execute_reply":"2026-09-23T19:26:33.782252Z"}},"outputs":[],"execution_count":null}]}