{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.13.15","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":"import os\n\nfor folder, _, files in os.walk(\"/kaggle/input\"):\n    print(folder, \"->\", len(files), \"files\")\n    for f in files[:3]:\n        print(\"   \", f)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-10-03T16:59:57.336731Z","iopub.execute_input":"2026-10-03T16:59:57.338172Z","iopub.status.idle":"2026-10-03T16:59:57.350277Z","shell.execute_reply.started":"2026-10-03T16:59:57.338127Z","shell.execute_reply":"2026-10-03T16:59:57.348933Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, zipfile, glob\nimport pandas as pd\n\nbase = \"/kaggle/input/competitions/galaxy-zoo-the-galaxy-challenge\"\nprint(os.listdir(base))\n\nsol_zip = glob.glob(base + \"/*solutions*.zip\")[0]\nwith zipfile.ZipFile(sol_zip) as z:\n    z.extractall(\"/kaggle/working\")\n\ncsv_path = glob.glob(\"/kaggle/working/*solutions*.csv\")[0]\ndf = pd.read_csv(csv_path)\nprint(df.shape)\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T16:59:57.352363Z","iopub.execute_input":"2026-10-03T16:59:57.352872Z","iopub.status.idle":"2026-10-03T16:59:57.958148Z","shell.execute_reply.started":"2026-10-03T16:59:57.352841Z","shell.execute_reply":"2026-10-03T16:59:57.956893Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, zipfile, glob\nimport pandas as pd\n\nbase = \"/kaggle/input/competitions/galaxy-zoo-the-galaxy-challenge\"\n\nsol_zip = glob.glob(base + \"/*solutions*.zip\")[0]\nwith zipfile.ZipFile(sol_zip) as z:\n    z.extractall(\"/kaggle/working\")\n\ndf = pd.read_csv(glob.glob(\"/kaggle/working/*solutions*.csv\")[0])\n\nlabels = df[[\"Class1.1\", \"Class1.2\", \"Class1.3\"]].idxmax(axis=1)\nnames = {\"Class1.1\": \"smooth\", \"Class1.2\": \"features\", \"Class1.3\": \"star_or_artifact\"}\ndf[\"label\"] = labels.map(names)\nprint(df[\"label\"].value_counts())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T16:59:57.959779Z","iopub.execute_input":"2026-10-03T16:59:57.960757Z","iopub.status.idle":"2026-10-03T16:59:58.51886Z","shell.execute_reply.started":"2026-10-03T16:59:57.960719Z","shell.execute_reply":"2026-10-03T16:59:58.517504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile, glob\nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\ndf = df[df[\"label\"] != \"star_or_artifact\"].reset_index(drop=True)\nprint(df[\"label\"].value_counts())\n\nimg_zip = glob.glob(base + \"/images_training*.zip\")[0]\nwith zipfile.ZipFile(img_zip) as z:\n    z.extractall(\"/kaggle/working\")\n\nimg_dir = glob.glob(\"/kaggle/working/images_training*\")[0]\nprint(img_dir, len(os.listdir(img_dir)))\n\nsample = df.sample(6, random_state=1)\nfig, axes = plt.subplots(2, 3, figsize=(9, 6))\nfor ax, (_, row) in zip(axes.flat, sample.iterrows()):\n    ax.imshow(Image.open(f\"{img_dir}/{int(row.GalaxyID)}.jpg\"))\n    ax.set_title(row.label)\n    ax.axis(\"off\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T16:59:58.520567Z","iopub.execute_input":"2026-10-03T16:59:58.52121Z","iopub.status.idle":"2026-10-03T17:00:22.531034Z","shell.execute_reply.started":"2026-10-03T16:59:58.521174Z","shell.execute_reply":"2026-10-03T17:00:22.529766Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom sklearn.model_selection import train_test_split\n\nsmall = pd.concat([\n    df[df.label == \"smooth\"].sample(6000, random_state=1),\n    df[df.label == \"features\"].sample(6000, random_state=1),\n]).sample(frac=1, random_state=1).reset_index(drop=True)\n\ndef load(gid):\n    im = Image.open(f\"{img_dir}/{gid}.jpg\").crop((106, 106, 318, 318)).resize((64, 64))\n    return np.asarray(im, dtype=\"uint8\")\n\nX = np.stack([load(g) for g in small.GalaxyID])\ny = (small.label == \"features\").astype(\"int\").values\nprint(X.shape, y.shape, y.mean())\n\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=1, stratify=y)\nprint(X_train.shape, X_val.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T17:00:22.533788Z","iopub.execute_input":"2026-10-03T17:00:22.534252Z","iopub.status.idle":"2026-10-03T17:00:44.012947Z","shell.execute_reply.started":"2026-10-03T17:00:22.534215Z","shell.execute_reply":"2026-10-03T17:00:44.011481Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow import keras\nfrom tensorflow.keras import layers\n\nXtr = X_train.astype(\"float32\") / 255.0\nXva = X_val.astype(\"float32\") / 255.0\n\nmodel = keras.Sequential([\n    layers.Input(shape=(64, 64, 3)),\n    layers.Conv2D(16, 3, activation=\"relu\"),\n    layers.MaxPooling2D(),\n    layers.Conv2D(32, 3, activation=\"relu\"),\n    layers.MaxPooling2D(),\n    layers.Conv2D(64, 3, activation=\"relu\"),\n    layers.MaxPooling2D(),\n    layers.Flatten(),\n    layers.Dropout(0.3),\n    layers.Dense(64, activation=\"relu\"),\n    layers.Dense(1, activation=\"sigmoid\"),\n])\nmodel.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\nhistory = model.fit(Xtr, y_train, validation_data=(Xva, y_val), epochs=8, batch_size=64)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T17:00:44.014435Z","iopub.execute_input":"2026-10-03T17:00:44.014839Z","iopub.status.idle":"2026-10-03T17:02:53.464124Z","shell.execute_reply.started":"2026-10-03T17:00:44.014807Z","shell.execute_reply":"2026-10-03T17:02:53.46284Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix, classification_report\n\nplt.figure(figsize=(6, 4))\nplt.plot(history.history[\"accuracy\"], label=\"train\")\nplt.plot(history.history[\"val_accuracy\"], label=\"validation\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend()\nplt.savefig(\"accuracy_curve.png\", dpi=150)\nplt.show()\n\npred = (model.predict(Xva) > 0.5).astype(int).ravel()\ncm = confusion_matrix(y_val, pred)\nprint(cm)\nprint(classification_report(y_val, pred, target_names=[\"smooth\", \"features\"]))\n\nfig, ax = plt.subplots(figsize=(4, 4))\nax.imshow(cm, cmap=\"Blues\")\nax.set_xticks([0, 1])\nax.set_xticklabels([\"smooth\", \"features\"])\nax.set_yticks([0, 1])\nax.set_yticklabels([\"smooth\", \"features\"])\nax.set_xlabel(\"Predicted\")\nax.set_ylabel(\"Actual\")\nfor i in range(2):\n    for j in range(2):\n        ax.text(j, i, cm[i, j], ha=\"center\", va=\"center\")\nplt.savefig(\"confusion_matrix.png\", dpi=150)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-03T17:02:53.465877Z","iopub.execute_input":"2026-10-03T17:02:53.466401Z","iopub.status.idle":"2026-10-03T17:02:55.490153Z","shell.execute_reply.started":"2026-10-03T17:02:53.466369Z","shell.execute_reply":"2026-10-03T17:02:55.488978Z"}},"outputs":[],"execution_count":null}]}