{"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":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":131587,"databundleVersionId":15786880}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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 numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:28:51.000830Z","iopub.execute_input":"2026-04-18T10:28:51.001593Z","iopub.status.idle":"2026-04-18T10:29:00.738765Z","shell.execute_reply.started":"2026-04-18T10:28:51.001560Z","shell.execute_reply":"2026-04-18T10:29:00.737900Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models, optimizers\nfrom tensorflow.keras.preprocessing import image\nfrom tqdm import tqdm\n\n# Device (GPU automatically handled in TensorFlow)\ngpus = tf.config.list_physical_devices('GPU')\ndevice = \"GPU\" if gpus else \"CPU\"\nprint(f\"Using device: {device}\")\n\nBASE_DIR = '/kaggle/input/competitions/cs-460-muffin-vs-chihuahua-classification-challenge'\nTRAIN_DIR = f'{BASE_DIR}/train'\nTEST_DIR = f'{BASE_DIR}/kaggle_test_final'\n\nBATCH_SIZE = 32\nEPOCHS = 5\nLEARNING_RATE = 0.001","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:29:55.918033Z","iopub.execute_input":"2026-04-18T10:29:55.918861Z","iopub.status.idle":"2026-04-18T10:29:55.924475Z","shell.execute_reply.started":"2026-04-18T10:29:55.918824Z","shell.execute_reply":"2026-04-18T10:29:55.923733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Image transformations\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nIMG_SIZE = (224, 224)\n\n# 🔹 Image transformations (equivalent to PyTorch transforms)\ndef imagenet_preprocess(x):\n    return tf.keras.applications.resnet50.preprocess_input(x)\n\ntrain_datagen = ImageDataGenerator(\n    preprocessing_function=imagenet_preprocess,\n    rotation_range=30,\n    zoom_range=0.3,\n    shear_range=0.2,\n    horizontal_flip=True\n)\n\ntest_datagen = ImageDataGenerator(\n    preprocessing_function=imagenet_preprocess\n)\n\n\n# 🔹 Load Training Data (ImageFolder + DataLoader equivalent)\ntry:\n    train_generator = train_datagen.flow_from_directory(\n        TRAIN_DIR,\n        target_size=IMG_SIZE,\n        batch_size=BATCH_SIZE,\n        class_mode='binary',\n        shuffle=True\n    )\n\n    classes = list(train_generator.class_indices.keys())\n    print(f\"Classes found: {classes}\")\n\nexcept Exception as e:\n    print(\"Error loading training data. Ensure your training folder has 'muffin' and 'chihuahua' subdirectories.\")\n    print(e)\n\n\n# 🔹 Custom Test Dataset (equivalent logic)\ntest_images = []\nimage_names = []\n\nfor img_name in os.listdir(TEST_DIR):\n    if img_name.endswith(('.jpg', '.png')):\n        img_path = os.path.join(TEST_DIR, img_name)\n\n        img = tf.keras.preprocessing.image.load_img(img_path, target_size=IMG_SIZE)\n        img = tf.keras.preprocessing.image.img_to_array(img)\n        img = tf.keras.applications.resnet50.preprocess_input(img)\n\n        test_images.append(img)\n        image_names.append(img_name)\n\n# Convert to tensor\ntest_images = np.array(test_images)\n\n# 🔹 DataLoader equivalent\ntest_dataset = tf.data.Dataset.from_tensor_slices((test_images, image_names))\ntest_dataset = test_dataset.batch(BATCH_SIZE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:43:03.099384Z","iopub.execute_input":"2026-04-18T10:43:03.099702Z","iopub.status.idle":"2026-04-18T10:43:16.809131Z","shell.execute_reply.started":"2026-04-18T10:43:03.099673Z","shell.execute_reply":"2026-04-18T10:43:16.808503Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models, optimizers\n\n# 🔹 Load pre-trained ResNet (closest to ResNet18 available in Keras)\nbase_model = tf.keras.applications.ResNet50(\n    weights='imagenet',\n    include_top=False,\n    input_shape=(224, 224, 3)\n)\n\n# 🔹 Freeze base model (same as using pretrained without training initially)\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# 🔹 Modify final layer (equivalent to model.fc = nn.Linear(..., 2))\nx = base_model.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\noutput = layers.Dense(2, activation='softmax')(x)\n\nmodel = models.Model(inputs=base_model.input, outputs=output)\n\n# 🔹 Loss + Optimizer (equivalent to CrossEntropyLoss + Adam)\nmodel.compile(\n    optimizer=optimizers.Adam(learning_rate=LEARNING_RATE),\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:44:20.367282Z","iopub.execute_input":"2026-04-18T10:44:20.368020Z","iopub.status.idle":"2026-04-18T10:44:22.013420Z","shell.execute_reply.started":"2026-04-18T10:44:20.367988Z","shell.execute_reply":"2026-04-18T10:44:22.012870Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Starting Training...\")\n\nhistory = model.fit(\n    train_generator,\n    epochs=EPOCHS,\n   \n    verbose=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:46:31.795998Z","iopub.execute_input":"2026-04-18T10:46:31.796803Z","iopub.status.idle":"2026-04-18T10:52:44.430064Z","shell.execute_reply.started":"2026-04-18T10:46:31.796771Z","shell.execute_reply":"2026-04-18T10:52:44.429351Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\nprint(\"Starting Inference on Test Set...\")\n\npredictions = []\nfilenames = image_names   # from your earlier test loading step\n\n# 🔹 Get predictions (equivalent to model.eval() + no_grad())\nprobs = model.predict(test_images, batch_size=BATCH_SIZE)\n\n# 🔹 Convert probabilities → class index\npredicted_classes = np.argmax(probs, axis=1)\n\n# 🔹 Map index → class label (same as idx_to_class)\nidx_to_class = {v: k for k, v in train_generator.class_indices.items()}\n\nfor idx in predicted_classes:\n    predictions.append(idx_to_class[idx])\n\n# 🔹 Create submission DataFrame\nsubmission_df = pd.DataFrame({\n    'ID': filenames,\n    'Label': predictions   # change column name if Kaggle requires\n})\n\n# 🔹 Save CSV\nsubmission_df.to_csv('submission.csv', index=False)\n\nprint(\"Submission saved successfully as submission.csv!\")\nprint(submission_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-18T10:52:44.431488Z","iopub.execute_input":"2026-04-18T10:52:44.431716Z","iopub.status.idle":"2026-04-18T10:52:56.734868Z","shell.execute_reply.started":"2026-04-18T10:52:44.431693Z","shell.execute_reply":"2026-04-18T10:52:56.734221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}