{"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":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":3812,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":2715,"modelId":316}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Setup","metadata":{}},{"cell_type":"code","source":"import os\nimport sys\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np\nimport pandas as pd\nimport  tensorflow as tf\nimport tf_keras as tfk\nimport json \nimport random\n\nfrom sklearn.metrics import classification_report , confusion_matrix\nfrom sklearn.utils.class_weight import compute_class_weight\nfrom tensorflow_hub import KerasLayer\n\n\nfrom tf_keras.preprocessing import image\nfrom tf_keras.applications.imagenet_utils import preprocess_input, decode_predictions\nfrom tf_keras.preprocessing.image import ImageDataGenerator\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:02:57.586574Z","iopub.execute_input":"2025-07-15T00:02:57.586945Z","iopub.status.idle":"2025-07-15T00:03:19.106032Z","shell.execute_reply.started":"2025-07-15T00:02:57.586911Z","shell.execute_reply":"2025-07-15T00:03:19.105450Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def set_random_seed(seed_value=42):\n    random.seed(seed_value)\n    np.random.seed(seed_value)\n    tf.random.set_seed(seed_value)\n    os.environ['PYTHONHASHSEED'] = str(seed_value)\n\nset_random_seed(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:19.107027Z","iopub.execute_input":"2025-07-15T00:03:19.107533Z","iopub.status.idle":"2025-07-15T00:03:19.112106Z","shell.execute_reply.started":"2025-07-15T00:03:19.107513Z","shell.execute_reply":"2025-07-15T00:03:19.111448Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/test1.zip -d /kaggle/working/\n!unzip /kaggle/input/dogs-vs-cats/train.zip -d /kaggle/working/\n\n","metadata":{"trusted":true,"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"PATH = '/kaggle/working/train'\nTEST = '/kaggle/working/test1'\nIMG_WIDTH = 224\nIMG_HEIGHT = 224\nBATCH_SIZE = 32","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:35.523804Z","iopub.execute_input":"2025-07-15T00:03:35.524050Z","iopub.status.idle":"2025-07-15T00:03:35.528193Z","shell.execute_reply.started":"2025-07-15T00:03:35.524028Z","shell.execute_reply":"2025-07-15T00:03:35.527636Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"PATH","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:35.528996Z","iopub.execute_input":"2025-07-15T00:03:35.529514Z","iopub.status.idle":"2025-07-15T00:03:35.548127Z","shell.execute_reply.started":"2025-07-15T00:03:35.529487Z","shell.execute_reply":"2025-07-15T00:03:35.547603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nprint(os.path.exists(PATH))  # Pastikan ini True\nprint(os.path.exists(TEST))  # Pastikan ini True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:35.548830Z","iopub.execute_input":"2025-07-15T00:03:35.549121Z","iopub.status.idle":"2025-07-15T00:03:35.565112Z","shell.execute_reply.started":"2025-07-15T00:03:35.549103Z","shell.execute_reply":"2025-07-15T00:03:35.564588Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load Image","metadata":{}},{"cell_type":"code","source":"filepaths = []\nlabels = []\n\nfor fname in os.listdir(PATH):\n    if fname.startswith(\"cat\"):\n        labels.append(\"cat\")\n    elif fname.startswith(\"dog\"):\n        labels.append(\"dog\")\n    else:\n        continue\n    filepaths.append(os.path.join(PATH, fname))\n\ndf = pd.DataFrame({\n    'filename': filepaths,\n    'class': labels\n})\n\ndatagen = ImageDataGenerator(rescale=1/255, validation_split=0.2)\n\ntrain_generator = datagen.flow_from_dataframe(\n    dataframe=df,\n    x_col=\"filename\",\n    y_col=\"class\",\n    target_size=(IMG_WIDTH, IMG_HEIGHT),\n    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",\n    subset=\"training\",\n    shuffle=True\n)\n\nval_generator = datagen.flow_from_dataframe(\n    dataframe=df,\n    x_col=\"filename\",\n    y_col=\"class\",\n    target_size=(IMG_WIDTH, IMG_HEIGHT),\n    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",\n    subset=\"validation\",\n    shuffle=False\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:35.565868Z","iopub.execute_input":"2025-07-15T00:03:35.566118Z","iopub.status.idle":"2025-07-15T00:03:35.983624Z","shell.execute_reply.started":"2025-07-15T00:03:35.566092Z","shell.execute_reply":"2025-07-15T00:03:35.982868Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_files = os.listdir(TEST)\ndf_test = pd.DataFrame({'filename': [os.path.join(TEST, fname) for fname in test_files]})\n\ntest_datagen = ImageDataGenerator(rescale=1/255)\n\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe=df_test,\n    x_col=\"filename\",\n    y_col=None,  # Karena tidak ada label\n    target_size=(IMG_WIDTH, IMG_HEIGHT),\n    batch_size=BATCH_SIZE,\n    class_mode=None,\n    shuffle=False\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:35.984612Z","iopub.execute_input":"2025-07-15T00:03:35.984892Z","iopub.status.idle":"2025-07-15T00:03:36.083868Z","shell.execute_reply.started":"2025-07-15T00:03:35.984873Z","shell.execute_reply":"2025-07-15T00:03:36.083155Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dict_labels = {value : key for key, value in train_generator.class_indices.items()}\n\nfor key, value in dict_labels.items():\n    print(f'{key} : {value}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:36.084669Z","iopub.execute_input":"2025-07-15T00:03:36.084885Z","iopub.status.idle":"2025-07-15T00:03:36.089252Z","shell.execute_reply.started":"2025-07-15T00:03:36.084869Z","shell.execute_reply":"2025-07-15T00:03:36.088444Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_labels = train_generator.classes\n\nclass_weight = compute_class_weight(\n    class_weight = 'balanced',\n    classes = np.unique(train_labels),\n    y = train_labels\n)\n\nclass_weight = dict(enumerate(class_weight))\nclass_weight","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:36.091346Z","iopub.execute_input":"2025-07-15T00:03:36.091623Z","iopub.status.idle":"2025-07-15T00:03:36.110162Z","shell.execute_reply.started":"2025-07-15T00:03:36.091607Z","shell.execute_reply":"2025-07-15T00:03:36.109485Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n## EDA","metadata":{}},{"cell_type":"code","source":"class_labels = list(train_generator.class_indices.keys())\n\ntrain_counts = train_generator.classes\nval_counts = val_generator.classes\n\ntrain_total = len(train_counts)\nval_total = len(val_counts)\n\ntrain_class_counts = np.bincount(train_counts)\nval_class_counts = np.bincount(val_counts)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:36.110904Z","iopub.execute_input":"2025-07-15T00:03:36.111093Z","iopub.status.idle":"2025-07-15T00:03:36.125255Z","shell.execute_reply.started":"2025-07-15T00:03:36.111079Z","shell.execute_reply":"2025-07-15T00:03:36.124581Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(18, 6))\nsns.barplot(x=['Train', 'Validation'], y=[train_total, val_total], palette='Blues_d')\nfor i, txt in enumerate([train_total, val_total]):\n    plt.annotate(txt, (i, txt), ha='center', va='bottom')\nplt.title('Total Number of Samples in Train, Validation, and Test Sets')\nplt.ylabel('Number of Samples')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:36.126058Z","iopub.execute_input":"2025-07-15T00:03:36.126256Z","iopub.status.idle":"2025-07-15T00:03:36.471638Z","shell.execute_reply.started":"2025-07-15T00:03:36.126242Z","shell.execute_reply":"2025-07-15T00:03:36.470766Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images, labels = next(train_generator)\n\nfig, axes = plt.subplots(nrows=2, ncols=3, figsize=(12, 8))\n\nfor i, ax in enumerate(axes.flatten()):\n    idx = np.random.randint(0, images.shape[0])\n    img = images[idx]\n    label = labels[idx]\n    \n    ax.imshow(img)\n    ax.axis('off')\n    ax.set_title(dict_labels[np.argmax(label)])\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:36.472666Z","iopub.execute_input":"2025-07-15T00:03:36.472974Z","iopub.status.idle":"2025-07-15T00:03:37.701129Z","shell.execute_reply.started":"2025-07-15T00:03:36.472948Z","shell.execute_reply":"2025-07-15T00:03:37.700313Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n# Modelling","metadata":{}},{"cell_type":"code","source":"num_classes = len(train_generator.class_indices)\nnum_classes","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:37.702217Z","iopub.execute_input":"2025-07-15T00:03:37.702827Z","iopub.status.idle":"2025-07-15T00:03:37.707669Z","shell.execute_reply.started":"2025-07-15T00:03:37.702802Z","shell.execute_reply":"2025-07-15T00:03:37.706921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def swin(pretrained):\n    tfk.backend.clear_session()\n\n    input = tfk.layers.Input(shape=(224,224,3))\n\n    x = KerasLayer(\n        pretrained,\n        trainable = False\n    )(input)\n    x = tfk.layers.Flatten()(x)\n    x = tfk.layers.Dropout(0.2)(x)\n\n    output = tfk.layers.Dense(num_classes, activation='softmax')(x)\n    model = tfk.Model(inputs=input, outputs= output)\n\n    model.compile(\n        optimizer=tfk.optimizers.Adam(\n            learning_rate=0.001,\n            beta_1=0.9,\n            beta_2=0.999,\n            epsilon=1e-7,\n        ),\n        loss=\"categorical_crossentropy\",\n        metrics=[\n            tfk.metrics.AUC(name=\"auc\"), \n            \"accuracy\",\n            tfk.metrics.Precision(name=\"precision\"),\n            tfk.metrics.Recall(name=\"recall\")\n        ]\n    )\n    \n    return model\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:37.708466Z","iopub.execute_input":"2025-07-15T00:03:37.708688Z","iopub.status.idle":"2025-07-15T00:03:37.727039Z","shell.execute_reply.started":"2025-07-15T00:03:37.708673Z","shell.execute_reply":"2025-07-15T00:03:37.726101Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_and_preprocess_image(img_path):\n    img = image.load_img(img_path, target_size=(IMG_WIDTH,IMG_HEIGHT))\n    img_array = image.img_to_array(img)\n    img_array = np.expand_dims(img_array, axis = 0)\n    img_array = preprocess_input(img_array, mode='tf', data_format=None)\n    return img, img_array\n\n\ndef predict_image(model):\n    base_path = '/kaggle/input/brain-tumor-mri-dataset/Testing'\n\n    with open ('/kaggle/working/labels.json','r') as label_file:\n        class_names = json.load(label_file)\n\n    selected_images = []\n    for class_name in os.listdir(base_path):\n        class_path = os.path.join(base_path, class_name)\n        if of.path.isdir(class_path):\n            img_files = os.listdir(class_path)\n            for img_file in img_files:\n                img_path = os.path.join(class_path, img_file)\n                selected_images.append((class_name, img_path))\n\n    max_images = min(len(selected_images),15)\n    np.random.shuffle(selected_images)\n    selected_images = selected_images[:max_images]\n\n    fig, axes = plt.subplots(3,5,figsize=(20,12))\n    axes = axes.flatten()\n\n    for idx in range(max_images):\n        actual_class, img_path = selected_images[idx]\n        img, img_array = load_and_preprocess_images(img_path)\n        predictions = model.predict(img_array)\n        predicted_class = np.argmax(predictions, axis=1)[0]\n        predicted_class_name = class_name[str(predicted_class)]\n\n        axes[idx].imshow(img)\n        axes[idx].axis('off')\n        color = 'red' if actual_class != predicred_class_name else ' black'\n        axes[idx].set_title(f'Actual : {actual_class}\\n Predicted : {predicted_class_name}', color = color)\n\n    for idx in range(max_images, len(axes)):\n        axes[idx].axis('off')\n\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:37.727955Z","iopub.execute_input":"2025-07-15T00:03:37.728209Z","iopub.status.idle":"2025-07-15T00:03:37.745233Z","shell.execute_reply.started":"2025-07-15T00:03:37.728188Z","shell.execute_reply":"2025-07-15T00:03:37.744705Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_confusion_matrix(model, model_name):\n    y_pred = np.argmax(model.predic(test_generator), axos = 1).tolist()\n    y_true = test_generator.classes.tolist()\n\n    cm = confusion_matrix(y_true, y_pred)\n    plt.figure(figsize=(10,8))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xtictlabels=test_generator.class_indices.keys(), yticklabels=test_generator.class_indices.keys())\n    plt.ylabel('Actual')\n    plt.xlabel('Predicted')\n    plt.title(f'{model_name} Confusion Matrix')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:37.746023Z","iopub.execute_input":"2025-07-15T00:03:37.746230Z","iopub.status.idle":"2025-07-15T00:03:37.765830Z","shell.execute_reply.started":"2025-07-15T00:03:37.746208Z","shell.execute_reply":"2025-07-15T00:03:37.765162Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"swin_sp4 = swin(\"/kaggle/input/swin/tensorflow2/small-patch4-window7-224/1\")\nswin_sp4.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:03:37.766595Z","iopub.execute_input":"2025-07-15T00:03:37.766809Z","iopub.status.idle":"2025-07-15T00:05:38.996007Z","shell.execute_reply.started":"2025-07-15T00:03:37.766794Z","shell.execute_reply":"2025-07-15T00:05:38.995433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"swin_sp4.fit(\n    train_generator, epochs=30,\n    validation_data=val_generator,\n    callbacks=[tfk.callbacks.CSVLogger('swin_sp4.csv')],\n    class_weight = class_weight\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T00:05:38.996766Z","iopub.execute_input":"2025-07-15T00:05:38.997027Z","iopub.status.idle":"2025-07-15T02:32:05.098058Z","shell.execute_reply.started":"2025-07-15T00:05:38.997009Z","shell.execute_reply":"2025-07-15T02:32:05.097191Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n# Test Data","metadata":{}},{"cell_type":"code","source":"preds = swin_sp4.predict(test_generator, verbose=1)\npreds","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:32:05.108017Z","iopub.execute_input":"2025-07-15T02:32:05.108239Z","iopub.status.idle":"2025-07-15T02:34:33.431742Z","shell.execute_reply.started":"2025-07-15T02:32:05.108222Z","shell.execute_reply":"2025-07-15T02:34:33.430635Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_labels_idx = np.argmax(preds, axis=1)\n\n# Mapping dari index ke label:\nlabel_map = {v: k for k, v in train_generator.class_indices.items()}\n\npred_labels = [label_map[idx] for idx in pred_labels_idx]\nlen(pred_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:16.555564Z","iopub.execute_input":"2025-07-15T02:41:16.556073Z","iopub.status.idle":"2025-07-15T02:41:16.564450Z","shell.execute_reply.started":"2025-07-15T02:41:16.556049Z","shell.execute_reply":"2025-07-15T02:41:16.563710Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission = pd.read_csv('/kaggle/input/dogs-vs-cats/sampleSubmission.csv')\nsample_submission.head(),sample_submission.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:18.036624Z","iopub.execute_input":"2025-07-15T02:41:18.036939Z","iopub.status.idle":"2025-07-15T02:41:18.047039Z","shell.execute_reply.started":"2025-07-15T02:41:18.036918Z","shell.execute_reply":"2025-07-15T02:41:18.046348Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission['label'] = pred_labels\nsample_submission.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:19.821224Z","iopub.execute_input":"2025-07-15T02:41:19.821776Z","iopub.status.idle":"2025-07-15T02:41:19.830510Z","shell.execute_reply.started":"2025-07-15T02:41:19.821749Z","shell.execute_reply":"2025-07-15T02:41:19.829749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission['label'] = sample_submission['label'].replace({'dog': 1, 'cat': 0})\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:22.978349Z","iopub.execute_input":"2025-07-15T02:41:22.978646Z","iopub.status.idle":"2025-07-15T02:41:22.987953Z","shell.execute_reply.started":"2025-07-15T02:41:22.978623Z","shell.execute_reply":"2025-07-15T02:41:22.987295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:24.335819Z","iopub.execute_input":"2025-07-15T02:41:24.336093Z","iopub.status.idle":"2025-07-15T02:41:24.344925Z","shell.execute_reply.started":"2025-07-15T02:41:24.336075Z","shell.execute_reply":"2025-07-15T02:41:24.344109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T02:41:27.253191Z","iopub.execute_input":"2025-07-15T02:41:27.253905Z","iopub.status.idle":"2025-07-15T02:41:27.268192Z","shell.execute_reply.started":"2025-07-15T02:41:27.253880Z","shell.execute_reply":"2025-07-15T02:41:27.267440Z"}},"outputs":[],"execution_count":null}]}