{"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":"gpu","dataSources":[{"sourceType":"competition","sourceId":6799,"databundleVersionId":4225553}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os, random\nimport torch\nimport torch.nn.functional as F\nimport torchvision.models as models\nimport torchvision.transforms as transforms\nfrom PIL import Image\nimport matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:15:46.966988Z","iopub.execute_input":"2026-05-05T15:15:46.967653Z","iopub.status.idle":"2026-05-05T15:15:46.971807Z","shell.execute_reply.started":"2026-05-05T15:15:46.967621Z","shell.execute_reply":"2026-05-05T15:15:46.970777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = \"cpu\"\n\nseed = 21522586  # MSSV\nrandom.seed(seed)\n\nDATA_PATH = \"/kaggle/input/competitions/imagenet-object-localization-challenge/ILSVRC/Data/CLS-LOC/val\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:19:50.639603Z","iopub.execute_input":"2026-05-05T15:19:50.64036Z","iopub.status.idle":"2026-05-05T15:19:50.6475Z","shell.execute_reply.started":"2026-05-05T15:19:50.640326Z","shell.execute_reply":"2026-05-05T15:19:50.646833Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cnn = models.resnet50(weights=\"IMAGENET1K_V1\").to(device).eval()\nvit = models.vit_b_16(weights=\"IMAGENET1K_V1\").to(device).eval()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:19:52.076609Z","iopub.execute_input":"2026-05-05T15:19:52.077272Z","iopub.status.idle":"2026-05-05T15:19:53.53624Z","shell.execute_reply.started":"2026-05-05T15:19:52.077241Z","shell.execute_reply":"2026-05-05T15:19:53.53559Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize((224,224)),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    )\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:19:55.804577Z","iopub.execute_input":"2026-05-05T15:19:55.804842Z","iopub.status.idle":"2026-05-05T15:19:55.809171Z","shell.execute_reply.started":"2026-05-05T15:19:55.80482Z","shell.execute_reply":"2026-05-05T15:19:55.808306Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"all_images = []\n\nfor root, dirs, files in os.walk(DATA_PATH):\n    for f in files:\n        if f.endswith(\".JPEG\"):\n            all_images.append(os.path.join(root, f))\n\nprint(\"Total images:\", len(all_images))\n\nselected_images = random.sample(all_images, 100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:01.316736Z","iopub.execute_input":"2026-05-05T15:20:01.317002Z","iopub.status.idle":"2026-05-05T15:20:19.856516Z","shell.execute_reply.started":"2026-05-05T15:20:01.316979Z","shell.execute_reply":"2026-05-05T15:20:19.855648Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_image(path):\n    img = Image.open(path).convert(\"RGB\")\n    return transform(img).unsqueeze(0).to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.85789Z","iopub.execute_input":"2026-05-05T15:20:19.858196Z","iopub.status.idle":"2026-05-05T15:20:19.862635Z","shell.execute_reply.started":"2026-05-05T15:20:19.858162Z","shell.execute_reply":"2026-05-05T15:20:19.861539Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_label(model, x):\n    with torch.no_grad():\n        return model(x).argmax(1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.864599Z","iopub.execute_input":"2026-05-05T15:20:19.864994Z","iopub.status.idle":"2026-05-05T15:20:19.875168Z","shell.execute_reply.started":"2026-05-05T15:20:19.864972Z","shell.execute_reply":"2026-05-05T15:20:19.874401Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def fgsm_attack(model, x, y, eps=0.03):\n    x = x.clone().detach().to(device)\n    x.requires_grad = True\n\n    output = model(x)\n    loss = F.cross_entropy(output, y)\n\n    model.zero_grad()\n    loss.backward()\n\n    grad = x.grad.data\n    x_adv = x + eps * grad.sign()\n    x_adv = torch.clamp(x_adv, 0, 1)\n\n    return x_adv.detach()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.876724Z","iopub.execute_input":"2026-05-05T15:20:19.877027Z","iopub.status.idle":"2026-05-05T15:20:19.885801Z","shell.execute_reply.started":"2026-05-05T15:20:19.877005Z","shell.execute_reply":"2026-05-05T15:20:19.885089Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def pgd_attack(model, x, y, eps=0.03, alpha=0.005, iters=10):\n    x = x.clone().detach().to(device)\n    x_adv = x.clone().detach()\n\n    for _ in range(iters):\n        x_adv.requires_grad = True\n\n        output = model(x_adv)\n        loss = F.cross_entropy(output, y)\n\n        model.zero_grad()\n        loss.backward()\n\n        grad = x_adv.grad.data\n        x_adv = x_adv + alpha * grad.sign()\n\n        eta = torch.clamp(x_adv - x, -eps, eps)\n        x_adv = torch.clamp(x + eta, 0, 1).detach()\n\n    return x_adv","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.886537Z","iopub.execute_input":"2026-05-05T15:20:19.886762Z","iopub.status.idle":"2026-05-05T15:20:19.899008Z","shell.execute_reply.started":"2026-05-05T15:20:19.886742Z","shell.execute_reply":"2026-05-05T15:20:19.898219Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def compute_asr(model, image_paths, attack_fn, **params):\n    success = 0\n    total = 0\n\n    for path in image_paths:\n        x = load_image(path)\n\n        y = get_label(model, x)\n\n        x_adv = attack_fn(model, x, y, **params)\n\n        pred_adv = model(x_adv).argmax(1)\n\n        if pred_adv != y:\n            success += 1\n\n        total += 1\n\n    return success / total","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.899908Z","iopub.execute_input":"2026-05-05T15:20:19.90013Z","iopub.status.idle":"2026-05-05T15:20:19.916109Z","shell.execute_reply.started":"2026-05-05T15:20:19.900107Z","shell.execute_reply":"2026-05-05T15:20:19.915376Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"CNN - FGSM:\", compute_asr(cnn, selected_images, fgsm_attack, eps=0.03))\nprint(\"CNN - PGD :\", compute_asr(cnn, selected_images, pgd_attack))\n\nprint(\"ViT - FGSM:\", compute_asr(vit, selected_images, fgsm_attack, eps=0.03))\nprint(\"ViT - PGD :\", compute_asr(vit, selected_images, pgd_attack))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T15:20:19.917276Z","iopub.execute_input":"2026-05-05T15:20:19.917818Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def transfer_asr(src_model, tgt_model, image_paths, attack_fn, **params):\n    success = 0\n    total = 0\n\n    for path in image_paths:\n        x = load_image(path)\n\n        y = get_label(src_model, x)\n\n        x_adv = attack_fn(src_model, x, y, **params)\n\n        pred = tgt_model(x_adv).argmax(1)\n\n        if pred != y:\n            success += 1\n\n        total += 1\n\n    return success / total","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"FGSM CNN → ViT:\", transfer_asr(cnn, vit, selected_images, fgsm_attack, eps=0.03))\nprint(\"PGD  CNN → ViT:\", transfer_asr(cnn, vit, selected_images, pgd_attack))\n\nprint(\"FGSM ViT → CNN:\", transfer_asr(vit, cnn, selected_images, fgsm_attack, eps=0.03))\nprint(\"PGD  ViT → CNN:\", transfer_asr(vit, cnn, selected_images, pgd_attack))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_attack(model, image_paths, attack_fn, n=5):\n    sample = random.sample(image_paths, n)\n\n    for path in sample:\n        img = Image.open(path).convert(\"RGB\")\n        x = transform(img).unsqueeze(0).to(device)\n\n        y = get_label(model, x)\n        x_adv = attack_fn(model, x, y)\n\n        clean = x.squeeze().permute(1,2,0).cpu()\n        adv = x_adv.squeeze().permute(1,2,0).cpu()\n\n        fig, ax = plt.subplots(1,2, figsize=(6,3))\n        ax[0].imshow(clean)\n        ax[0].set_title(\"Clean\")\n\n        ax[1].imshow(adv)\n        ax[1].set_title(\"Adversarial\")\n\n        plt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}