{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python"},"colab":{"provenance":[]},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":99053,"databundleVersionId":11875443,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"nh0Aj2VgwOE3","cell_type":"markdown","source":"# Starter Notebook\n\nWelcome to the coin classification competition! This notebook will help you get started by:\n1. Demonstrating **basic Exploratory Data Analysis** on the provided CSV files\n2. **Generating a random submission** as a baseline\n\nFeel free to use, remix, and build upon this starter to develop a more sophisticated model.","metadata":{"id":"nh0Aj2VgwOE3"}},{"id":"uqz5QQKbwOE4","cell_type":"code","source":"# Random imports\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom zipfile import ZipFile\nimport matplotlib.pyplot as plt\nimport cv2\nimport random\nimport os\nfrom collections import Counter","metadata":{"id":"uqz5QQKbwOE4"},"outputs":[],"execution_count":null},{"id":"d7a5346d","cell_type":"markdown","source":"### Kaggle stuff","metadata":{"id":"d7a5346d"}},{"id":"d4b15d95","cell_type":"code","source":"os.environ['KAGGLE_USERNAME']='YOUR_USERNAME'\nos.environ['KAGGLE_KEY']='YOUR_KAGGLE_KEY'","metadata":{"id":"d4b15d95"},"outputs":[],"execution_count":null},{"id":"cf996dd5","cell_type":"code","source":"!pip install -q -U kaggle","metadata":{"id":"cf996dd5"},"outputs":[],"execution_count":null},{"id":"a3fc4e13","cell_type":"code","source":"!kaggle competitions download -c dl4cv-coin-classification --force","metadata":{"id":"a3fc4e13","outputId":"76f5c886-0ee1-4ad5-e0d3-fa642fffbb77"},"outputs":[],"execution_count":null},{"id":"9c4j3en8wVfc","cell_type":"code","source":"!unzip dl4cv-coin-classification.zip","metadata":{"collapsed":true,"id":"9c4j3en8wVfc","jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"id":"a4MgkyqkwOE7","cell_type":"markdown","source":"## 1. Load Data\n\nWe'll read the CSV files: `train.csv` and `test.csv`. The `train.csv` includes both an `Id` (our unique image identifier) and a `Class` label.","metadata":{"id":"a4MgkyqkwOE7"}},{"id":"nprBPZLxwOE7","cell_type":"code","source":"train_df = pd.read_csv('kaggle/train.csv')\ntest_df = pd.read_csv('kaggle/test.csv')\n\nprint('Train shape:', train_df.shape)\nprint('Test shape:', test_df.shape)\n\ntrain_df.head()","metadata":{"id":"nprBPZLxwOE7","outputId":"744082dd-88f7-4781-93d0-d2012f2a6bf0"},"outputs":[],"execution_count":null},{"id":"SdSJhmRawOE7","cell_type":"markdown","source":"## 2. Basic Exploratory Data Analysis\nWe'll look at how many classes we have, and how many images per class.","metadata":{"id":"SdSJhmRawOE7"}},{"id":"tt8EXvc9wOE7","cell_type":"code","source":"num_classes = train_df['Class'].nunique()\nprint(f'Number of classes: {num_classes}')\n\nclass_counts = train_df['Class'].value_counts()\nclass_counts.head(10)","metadata":{"id":"tt8EXvc9wOE7","outputId":"056a3126-9df4-43e3-b026-01c3a6817da5"},"outputs":[],"execution_count":null},{"id":"R6LzBWrIwOE8","cell_type":"markdown","source":"### Distribution of the Top 10 Classes\n\nLet's visualize the 10 most common classes in the training set.","metadata":{"id":"R6LzBWrIwOE8"}},{"id":"HucHiSttwOE8","cell_type":"code","source":"top_10 = class_counts.head(10)\nplt.figure(figsize=(8, 4))\ntop_10.plot(kind='bar')\nplt.title('Top 10 Classes by Image Count')\nplt.xlabel('Class Name')\nplt.ylabel('Count')\nplt.show()","metadata":{"id":"HucHiSttwOE8","outputId":"35796a28-71a4-49ce-9b1d-98a8c874cedc"},"outputs":[],"execution_count":null},{"id":"4mc1d2LOwOE8","cell_type":"markdown","source":"### Quick Look at a Few Images\n\nIf you’d like to see what the images look like, you could do something like:","metadata":{"id":"4mc1d2LOwOE8"}},{"id":"7d2a687b","cell_type":"code","source":"some_id = random.choice(train_df['Id'].values)\nimage_path = os.path.join('kaggle/train', f'{some_id}.jpg')  # or .png, etc.\nimg = cv2.imread(image_path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nplt.imshow(img)\nplt.title('Class: ' + train_df.loc[train_df['Id'] == some_id, 'Class'].values[0])\nplt.show()","metadata":{"id":"7d2a687b","outputId":"c084fc2d-5ea9-468f-fe56-355385a3f6cb"},"outputs":[],"execution_count":null},{"id":"NDIWcCnPwOE8","cell_type":"markdown","source":"## 3. Challenges & Caveats\nBelow are some important details about this dataset:\n\n- **Class Imbalances**: Some coins have many samples, while others are relatively underrepresented.\n- **Mint Variations**: Coins of the same denomination might differ subtly due to different mints or yearly revisions.\n- **Type Variations**: Coins of the same denomination might have different types.\n- **Varied Conditions**: Tarnish, rust, and scratches can alter a coin’s appearance. Lighting and angle variations further increase complexity.\n- **Subtle Differences**: Denominations of euro coins can sometimes only be distinguished by edge patterns.","metadata":{"id":"NDIWcCnPwOE8"}},{"id":"eWzWmJNK7Uw4","cell_type":"markdown","source":"## Examples of mint and type variations\n\nAll images are 50 Cents,Euro,netherlands class, but have substantial differences.","metadata":{"id":"eWzWmJNK7Uw4"}},{"id":"yaQjUM2c7S4_","cell_type":"code","source":"\n\nfig, axes = plt.subplots(nrows=1, ncols=3, figsize=(16, 12))\n\nfor i, image_id in enumerate([11525, 11522, 11534]):\n  image_path = os.path.join('kaggle/train', f'{image_id}.jpg')\n  img = cv2.imread(image_path)\n  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n  axes[i].imshow(img)\n  axes[i].set_title(f'ID: {image_id}, 50 Cents,Euro,netherlands')\n  axes[i].axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"id":"yaQjUM2c7S4_","outputId":"7aa3e609-7788-447e-8d94-3cad17acf06a"},"outputs":[],"execution_count":null},{"id":"2BrxT_ez9lQ7","cell_type":"markdown","source":"## Subtle Differences\nLets take a look at 20, 50 cents and 1 euro from Germany. Note that the only difference between 20 and 50 cents is the pattern on the edge of the coin.","metadata":{"id":"2BrxT_ez9lQ7"}},{"id":"mAdR-r3m97Bb","cell_type":"code","source":"\nfig, axes = plt.subplots(nrows=1, ncols=3, figsize=(16, 12))\n\nfor i, image_id in enumerate([8780, 11308, 8829]):\n  image_path = os.path.join('kaggle/train', f'{image_id}.jpg')\n  img = cv2.imread(image_path)\n  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n  axes[i].imshow(img)\n  axes[i].set_title(f'ID: {image_id}, Euro,Germany')\n  axes[i].axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"id":"mAdR-r3m97Bb","outputId":"5be5a94f-8050-439d-8374-4e8522e03458"},"outputs":[],"execution_count":null},{"id":"VKyDWf9wwOE9","cell_type":"markdown","source":"## 4. Generate a Random Submission\nAs a quick baseline, we can create a ‘random classifier’ that:\n1. Collects the list of possible classes from `train.csv`.\n2. For each row in `test.csv`, randomly picks a class from our list.\n3. Writes out a `submission.csv` file with `[Id, Class]` columns.\n\nObviously, this won't be accurate, but it provides a simple template for how you’ll submit predictions to Kaggle.","metadata":{"id":"VKyDWf9wwOE9"}},{"id":"e_Fyox8TwOE9","cell_type":"code","source":"\nclasses = train_df['Class'].unique()\ntest_ids = test_df['Id'].values\n\npreds = np.random.choice(classes, size=len(test_ids))\n\nsubmission_df = pd.DataFrame({\n    'Id': test_ids,\n    'Class': preds\n})\n\nsubmission_df.to_csv('submission.csv', index=False)\nsubmission_df.head(10)","metadata":{"id":"e_Fyox8TwOE9","outputId":"67c5af66-e19c-443b-9eca-e200a7a20421"},"outputs":[],"execution_count":null},{"id":"083671ad","cell_type":"markdown","source":"## 5. Submission","metadata":{"id":"083671ad"}},{"id":"22a53b17","cell_type":"code","source":"!kaggle competitions submit -c dl4cv-coin-classification -f submission.csv -m \"test message\"","metadata":{"id":"22a53b17","outputId":"a302dc2c-a9e5-40fa-fe19-b49dd8e3b24d"},"outputs":[],"execution_count":null},{"id":"GPybV1CHwOE9","cell_type":"markdown","source":"## Next Steps\n- **Improve the Model**: Instead of random guesses, build a real image classifier using CNNs (e.g., PyTorch, Keras, TensorFlow, etc.)\n- **Data Augmentation**: Address class imbalance.\n- **Hyperparameter Tuning**: Try different architectures, optimizers, or transfer learning from a pretrained model.\n\nGood luck!","metadata":{"id":"GPybV1CHwOE9"}}]}