{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport glob\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport matplotlib.pyplot as plt\nimport subprocess\nimport zipfile\n\n# Install py7zr for .7z extraction\ntry:\n    import py7zr\n    print(\"py7zr is available\")\nexcept ImportError:\n    print(\"Installing py7zr...\")\n    subprocess.run([\"pip\", \"install\", \"py7zr\"], check=True)\n    import py7zr\n    print(\"py7zr installed successfully\")\n\n# Set random seeds for reproducibility\nnp.random.seed(42)\ntf.random.set_seed(42)\n\n# Define CIFAR-10 class names\nclass_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', \n               'dog', 'frog', 'horse', 'ship', 'truck']\n\nprint(\"TensorFlow version:\", tf.__version__)\nprint(\"GPU available:\", tf.config.list_physical_devices('GPU'))\n\n# Load CIFAR-10 data for training\n(x_train, y_train), (x_val, y_val) = tf.keras.datasets.cifar10.load_data()\n\n# Normalize pixel values to [0, 1]\nx_train = x_train.astype('float32') / 255.0\nx_val = x_val.astype('float32') / 255.0\n\n# Convert labels to categorical\ny_train = tf.keras.utils.to_categorical(y_train, 10)\ny_val = tf.keras.utils.to_categorical(y_val, 10)\n\nprint(f\"Training data shape: {x_train.shape}\")\nprint(f\"Training labels shape: {y_train.shape}\")\nprint(f\"Validation data shape: {x_val.shape}\")\nprint(f\"Validation labels shape: {y_val.shape}\")\n\n# Data augmentation\ndatagen = ImageDataGenerator(\n    rotation_range=15,\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    horizontal_flip=True,\n    zoom_range=0.1,\n    shear_range=0.1\n)\n\ndef create_cnn_model():\n    model = models.Sequential([\n        # First block\n        layers.Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)),\n        layers.BatchNormalization(),\n        layers.Conv2D(64, (3, 3), activation='relu', padding='same'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Dropout(0.3),   # ↑ from 0.25\n        \n        # Second block\n        layers.Conv2D(128, (3, 3), activation='relu', padding='same'),\n        layers.BatchNormalization(),\n        layers.Conv2D(128, (3, 3), activation='relu', padding='same'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Dropout(0.3),   # ↑ from 0.25\n        \n        # Third block\n        layers.Conv2D(256, (3, 3), activation='relu', padding='same'),\n        layers.BatchNormalization(),\n        layers.Conv2D(256, (3, 3), activation='relu', padding='same'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Dropout(0.3),   # ↑ from 0.25\n        \n        # Fourth block\n        layers.Conv2D(512, (3, 3), activation='relu', padding='same'),\n        layers.BatchNormalization(),\n        layers.Conv2D(512, (3, 3), activation='relu', padding='same'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Dropout(0.3),   # ↑ from 0.25\n        \n        # Dense layers\n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.BatchNormalization(),\n        layers.Dropout(0.4),   # ↓ from 0.5\n        layers.Dense(256, activation='relu'),\n        layers.BatchNormalization(),\n        layers.Dropout(0.4),   # ↓ from 0.5\n        layers.Dense(10, activation='softmax')\n    ])\n    \n    return model\n\n\n\n# # Create CNN model (inspired by VGG but smaller)\n# def create_cnn_model():\n#     model = models.Sequential([\n#         # First block\n#         layers.Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)),\n#         layers.BatchNormalization(),\n#         layers.Conv2D(64, (3, 3), activation='relu', padding='same'),\n#         layers.MaxPooling2D((2, 2)),\n#         layers.Dropout(0.25),\n        \n#         # Second block\n#         layers.Conv2D(128, (3, 3), activation='relu', padding='same'),\n#         layers.BatchNormalization(),\n#         layers.Conv2D(128, (3, 3), activation='relu', padding='same'),\n#         layers.MaxPooling2D((2, 2)),\n#         layers.Dropout(0.25),\n        \n#         # Third block\n#         layers.Conv2D(256, (3, 3), activation='relu', padding='same'),\n#         layers.BatchNormalization(),\n#         layers.Conv2D(256, (3, 3), activation='relu', padding='same'),\n#         layers.MaxPooling2D((2, 2)),\n#         layers.Dropout(0.25),\n        \n#         # Fourth block\n#         layers.Conv2D(512, (3, 3), activation='relu', padding='same'),\n#         layers.BatchNormalization(),\n#         layers.Conv2D(512, (3, 3), activation='relu', padding='same'),\n#         layers.MaxPooling2D((2, 2)),\n#         layers.Dropout(0.25),\n        \n#         # Dense layers\n#         layers.Flatten(),\n#         layers.Dense(512, activation='relu'),\n#         layers.BatchNormalization(),\n#         layers.Dropout(0.5),\n#         layers.Dense(256, activation='relu'),\n#         layers.BatchNormalization(),\n#         layers.Dropout(0.5),\n#         layers.Dense(10, activation='softmax')\n#     ])\n    \n#     return model\n\n# Create and compile model\nmodel = create_cnn_model()\n\n# Compile model with Adam optimizer\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n    loss='categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# Print model summary\nmodel.summary()\n\n# Define callbacks\ncallbacks = [\n    EarlyStopping(\n        monitor='val_accuracy',\n        patience=10,\n        restore_best_weights=True,\n        verbose=1\n    ),\n    ReduceLROnPlateau(\n        monitor='val_loss',\n        factor=0.2,\n        patience=5,\n        min_lr=1e-7,\n        verbose=1\n    )\n]\n\n# Train the model\nprint(\"Starting training...\")\nhistory = model.fit(\n    datagen.flow(x_train, y_train, batch_size=128),\n    epochs=100,\n    validation_data=(x_val, y_val),\n    callbacks=callbacks,\n    verbose=1,\n    steps_per_epoch=len(x_train) // 128\n)\n\n# Plot training history\ndef plot_training_history(history):\n    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n    \n    ax1.plot(history.history['accuracy'], label='Training Accuracy')\n    ax1.plot(history.history['val_accuracy'], label='Validation Accuracy')\n    ax1.set_title('Model Accuracy')\n    ax1.set_xlabel('Epoch')\n    ax1.set_ylabel('Accuracy')\n    ax1.legend()\n    \n    ax2.plot(history.history['loss'], label='Training Loss')\n    ax2.plot(history.history['val_loss'], label='Validation Loss')\n    ax2.set_title('Model Loss')\n    ax2.set_xlabel('Epoch')\n    ax2.set_ylabel('Loss')\n    ax2.legend()\n    \n    plt.tight_layout()\n    plt.show()\n\nplot_training_history(history)\n\n# Evaluate on CIFAR-10 validation set\nval_loss, val_accuracy = model.evaluate(x_val, y_val, verbose=0)\nprint(f\"CIFAR-10 Validation Accuracy: {val_accuracy:.4f}\")\n\n# Function to load Kaggle test images (using the suggested approach)\ndef load_test_images():\n    \"\"\"\n    Load test images from the Kaggle dataset.\n    This function will search for the test images, including extracting from .7z files.\n    \"\"\"\n    import zipfile\n    import py7zr\n    \n    # Check what's available in the input directory\n    print(\"Available directories in /kaggle/input/:\")\n    if os.path.exists('/kaggle/input/'):\n        for item in os.listdir('/kaggle/input/'):\n            item_path = f'/kaggle/input/{item}'\n            print(f\"  {item}/\")\n            # Show what's inside each directory\n            if os.path.isdir(item_path):\n                try:\n                    contents = os.listdir(item_path)\n                    for content in contents[:10]:  # Show first 10 items\n                        print(f\"    {content}\")\n                    if len(contents) > 10:\n                        print(f\"    ... and {len(contents) - 10} more items\")\n                except:\n                    print(\"    (cannot read contents)\")\n    \n    # Check if we have the test.7z file\n    test_7z_path = '/kaggle/input/cifar-10/test.7z'\n    if os.path.exists(test_7z_path):\n        print(f\"\\nFound test.7z file at: {test_7z_path}\")\n        print(\"Extracting test images from .7z file...\")\n        \n        # Create a directory to extract to\n        extract_dir = '/kaggle/working/test_images'\n        os.makedirs(extract_dir, exist_ok=True)\n        \n        try:\n            # Extract the .7z file\n            with py7zr.SevenZipFile(test_7z_path, mode='r') as archive:\n                archive.extractall(path=extract_dir)\n            \n            # Find the actual test directory after extraction\n            test_dir = None\n            for root, dirs, files in os.walk(extract_dir):\n                if any(f.endswith('.png') for f in files):\n                    test_dir = root\n                    break\n            \n            if test_dir:\n                print(f\"Successfully extracted test images to: {test_dir}\")\n                png_files = glob.glob(os.path.join(test_dir, '*.png'))\n                print(f\"Found {len(png_files)} PNG files\")\n            else:\n                print(\"No PNG files found after extraction\")\n                return None, None\n                \n        except Exception as e:\n            print(f\"Error extracting .7z file: {e}\")\n            print(\"Trying alternative extraction method...\")\n            \n            # Alternative: try using zipfile (sometimes .7z files work with this)\n            try:\n                with zipfile.ZipFile(test_7z_path, 'r') as zip_ref:\n                    zip_ref.extractall(extract_dir)\n                \n                # Find the actual test directory after extraction\n                test_dir = None\n                for root, dirs, files in os.walk(extract_dir):\n                    if any(f.endswith('.png') for f in files):\n                        test_dir = root\n                        break\n                \n                if test_dir:\n                    print(f\"Successfully extracted test images to: {test_dir}\")\n                    png_files = glob.glob(os.path.join(test_dir, '*.png'))\n                    print(f\"Found {len(png_files)} PNG files\")\n                else:\n                    print(\"No PNG files found after extraction\")\n                    return None, None\n                    \n            except Exception as e2:\n                print(f\"Alternative extraction also failed: {e2}\")\n                print(\"The .7z file might need manual extraction or a different method\")\n                return None, None\n    \n    else:\n        # Try other possible paths\n        possible_paths = [\n            '/kaggle/input/cifar-10/test',\n            '/kaggle/input/cifar10/test', \n            '/kaggle/input/cifar-10-test-images/test',\n            '/kaggle/input/d/safios/cifar-10/test',\n            '/kaggle/input/safios-cifar-10/test',\n            '/kaggle/input/cifar10-test/test'\n        ]\n        \n        # Also check all subdirectories for PNG files\n        if os.path.exists('/kaggle/input/'):\n            for root_item in os.listdir('/kaggle/input/'):\n                root_path = f'/kaggle/input/{root_item}'\n                if os.path.isdir(root_path):\n                    # Check if there's a test subdirectory\n                    test_path = os.path.join(root_path, 'test')\n                    if os.path.exists(test_path):\n                        possible_paths.append(test_path)\n                    # Also check if PNG files are directly in the root directory\n                    try:\n                        files_in_dir = os.listdir(root_path)\n                        if any(f.endswith('.png') for f in files_in_dir):\n                            possible_paths.append(root_path)\n                        # Check subdirectories too\n                        for subdir in files_in_dir:\n                            subdir_path = os.path.join(root_path, subdir)\n                            if os.path.isdir(subdir_path):\n                                try:\n                                    sub_files = os.listdir(subdir_path)\n                                    if any(f.endswith('.png') for f in sub_files):\n                                        possible_paths.append(subdir_path)\n                                except:\n                                    pass\n                    except:\n                        pass\n        \n        test_dir = None\n        for path in possible_paths:\n            if os.path.exists(path):\n                # Check if there are actually PNG files in this directory\n                png_files = glob.glob(os.path.join(path, '*.png'))\n                if png_files:\n                    test_dir = path\n                    print(f\"Found {len(png_files)} PNG files in: {path}\")\n                    break\n        \n        if test_dir is None:\n            print(\"No test.7z file found and no PNG directories located\")\n            return None, None\n    \n    print(f\"Using test directory: {test_dir}\")\n    \n    # Collect only PNG files\n    test_files = sorted(\n        glob.glob(os.path.join(test_dir, '*.png')),\n        key=lambda x: int(os.path.splitext(os.path.basename(x))[0])  # removes \".png\"\n    )\n    \n    print(f\"Found {len(test_files)} test images\")\n    \n    test_images = []\n    test_ids = []\n    \n    for file_path in test_files:\n        try:\n            img = Image.open(file_path).convert('RGB')\n            img = img.resize((32, 32))\n            img_array = np.array(img)\n            test_images.append(img_array)\n            \n            # Extract ID (filename without extension)\n            file_id = int(os.path.splitext(os.path.basename(file_path))[0])\n            test_ids.append(file_id)\n        except Exception as e:\n            print(f\"Error loading {file_path}: {e}\")\n    \n    return np.array(test_images), test_ids\n\n# Load test images\nprint(\"Loading Kaggle test images...\")\ntest_images, test_ids = load_test_images()\n\nif test_images is not None:\n    print(f\"Loaded {len(test_images)} test images\")\n    \n    # Preprocess test images\n    test_images = test_images.astype('float32') / 255.0\n    \n    # Make predictions on test set\n    print(\"Making predictions...\")\n    test_predictions = model.predict(test_images, batch_size=128, verbose=1)\n    test_pred_classes = np.argmax(test_predictions, axis=1)\n    \n    # Convert predictions to class names\n    test_pred_labels = [class_names[pred] for pred in test_pred_classes]\n    \n    # Create Kaggle Submission\n    submission_df = pd.DataFrame({\n        'id': test_ids,\n        'label': test_pred_labels\n    })\n    \n    # Sort by ID\n    submission_df = submission_df.sort_values('id').reset_index(drop=True)\n    \n    # Display sample predictions\n    print(\"\\nSample predictions:\")\n    print(submission_df.head(10))\n    \n    # Save submission file\n    submission_df.to_csv('submission.csv', index=False)\n    print(f\"\\nSubmission file saved as 'submission.csv' with {len(submission_df)} predictions\")\n    \n    # Display submission statistics\n    print(\"\\nPrediction distribution:\")\n    print(submission_df['label'].value_counts().sort_index())\n    \nelse:\n    print(\"\\n\" + \"=\"*70)\n    print(\"SOLUTION: You need a DIFFERENT dataset with individual PNG images!\")\n    print(\"=\"*70)\n    print(\"\\nWhat you currently have:\")\n    print(\"- Standard CIFAR-10 dataset (with pickled/binary files)\")\n    print(\"\\nWhat you need:\")\n    print(\"- CIFAR-10 competition dataset with individual PNG test images\")\n    print(\"\\nHow to get it:\")\n    print(\"1. Click '+ Add input' in your notebook\")\n    print(\"2. Search for these specific datasets:\")\n    print(\"   - 'cifar-10 competition test'\")\n    print(\"   - 'safios/cifar-10' (this one should work)\")\n    print(\"   - 'cifar 10 png images'\")\n    print(\"3. Look for a dataset that mentions 'PNG files' or 'individual images'\")\n    print(\"4. The dataset should be around 100-300MB (not just a few MB)\")\n    print(\"\\nOR download from the competition directly:\")\n    print(\"https://www.kaggle.com/c/cifar-10/data\")\n    print(\"=\"*70)\n    \n    # Create a submission using validation predictions for now\n    print(\"\\nCreating temporary submission using validation set predictions...\")\n    \n    # Use the CIFAR-10 validation set to create a sample submission\n    val_predictions = model.predict(x_val, batch_size=128, verbose=1)\n    val_pred_classes = np.argmax(val_predictions, axis=1)\n    val_pred_labels = [class_names[pred] for pred in val_pred_classes]\n    \n    # Create a sample submission (first 300 predictions to match typical test size)\n    sample_size = min(300, len(val_pred_labels))\n    submission_df = pd.DataFrame({\n        'id': list(range(1, sample_size + 1)),\n        'label': val_pred_labels[:sample_size]\n    })\n    \n    submission_df.to_csv('submission.csv', index=False)\n    print(f\"\\nTemporary submission.csv created with {len(submission_df)} entries\")\n    print(\"NOTE: This uses validation set predictions - you need real test images for final submission!\")\n    \n    print(f\"\\nSample of temporary submission:\")\n    print(submission_df.head(10))\n    print(f\"\\nPrediction distribution:\")\n    print(submission_df['label'].value_counts().sort_index())\n\n# Save the model\nmodel.save('cifar10_model.h5')\nprint(\"Model saved as 'cifar10_model.h5'\")\n\nprint(f\"\\nFinal validation accuracy: {val_accuracy:.4f}\")\nprint(\"Training completed successfully!\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-22T17:07:07.755698Z","iopub.execute_input":"2025-09-22T17:07:07.755950Z","iopub.status.idle":"2025-09-22T17:27:00.696777Z","shell.execute_reply.started":"2025-09-22T17:07:07.755933Z","shell.execute_reply":"2025-09-22T17:27:00.695881Z"}},"outputs":[],"execution_count":null}]}