Upload 2 files
Browse files- LookThemSTL10V1.ipynb +1 -0
- LookThem_STL.pth +3 -0
LookThemSTL10V1.ipynb
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"gpuType":"T4","authorship_tag":"ABX9TyO/gSSzaBRRCZ/rYhoC/jGO"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"accelerator":"GPU"},"cells":[{"cell_type":"code","source":["import os\n","import zipfile\n","import urllib.request\n","import math\n","import torch\n","import torch.nn as nn\n","import torch.nn.functional as F\n","import torch.optim as optim\n","from torch.utils.data import DataLoader\n","from torchvision import datasets, transforms\n","\n","import torch\n","import torchvision\n","import torchvision.transforms as transforms\n","from torch.utils.data import DataLoader\n","\n","# 1. Atur transformasi (Resize ke target resolusi Anda, misal 128x128 atau 256x256)\n","transform_train = transforms.Compose([\n"," transforms.RandomHorizontalFlip(),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","transform_test = transforms.Compose([\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","# 2. Download dan Load Dataset (Otomatis masuk ke folder ./data)\n","# Ukuran download terkompresi hanya sekitar ~1.9 GB\n","train_dataset = torchvision.datasets.STL10(root='./data', split='train', download=True, transform=transform_train)\n","test_dataset = torchvision.datasets.STL10(root='./data', split='test', download=True, transform=transform_test)\n","\n","# 3. Siapkan DataLoader\n","train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=2)\n","val_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=2)\n","\n","print(f\"Jumlah data training: {len(train_dataset)}\")\n","print(f\"Jumlah data testing: {len(test_dataset)}\")\n","\n","\n","\n","# ==========================================\n","# 2. CORE LAYER: LOOKTHEM CORE LAYER\n","# ==========================================\n","class LookThemLayer(nn.Module):\n"," def __init__(self, num_tokens, in_features, hidden_dim):\n"," super(LookThemLayer, self).__init__()\n"," self.num_tokens = num_tokens\n"," self.in_features = in_features\n","\n"," self.mod1_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod1_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod1_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod1_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.mod2_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod2_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod2_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod2_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.trans_w = nn.Parameter(torch.randn(num_tokens, 1, 1))\n"," self.trans_b = nn.Parameter(torch.zeros(num_tokens, 1))\n"," self._init_weights()\n","\n"," def _init_weights(self):\n"," for w in [self.mod1_w1, self.mod2_w1, self.mod1_w2, self.mod2_w2, self.trans_w]:\n"," nn.init.kaiming_uniform_(w, a=math.sqrt(5))\n","\n"," def forward(self, x):\n"," N = self.num_tokens\n"," h1 = torch.einsum('bti,tij->btj', x, self.mod1_w1) + self.mod1_b1\n"," out_m1 = torch.einsum('btj,tjk->btk', F.gelu(h1), self.mod1_w2) + self.mod1_b2\n","\n"," h2 = torch.einsum('bti,tij->btj', x, self.mod2_w1) + self.mod2_b1\n"," out_m2 = torch.einsum('btj,tjk->btk', F.gelu(h2), self.mod2_w2) + self.mod2_b2\n","\n"," out_m2_safe = out_m2 + 1e-5\n"," compare = torch.tanh(out_m1.unsqueeze(2) / out_m2_safe.unsqueeze(1))\n"," compare2 = torch.tanh(out_m1.unsqueeze(1) / out_m2_safe.unsqueeze(2))\n","\n"," bias_reshaped = self.trans_b.view(1, 1, N, 1)\n"," trans_compare = torch.einsum('bije,jef->bijf', compare, self.trans_w) + bias_reshaped\n"," trans_compare2 = torch.einsum('bije,jef->bijf', compare2, self.trans_w) + bias_reshaped\n","\n"," interaksi = (trans_compare * x.unsqueeze(2) + trans_compare2 * x.unsqueeze(1)) / 2\n"," mask = 1.0 - torch.eye(N, device=x.device)\n"," interaksi_masked = interaksi * mask.view(1, N, N, 1)\n","\n"," return interaksi_masked.sum(dim=2) / (N - 1.0)\n","\n","# ==========================================\n","# 3. INDUK ARSITEKTUR: LOOKTHEM V5 (STANDARD CONV STREAM B)\n","# ==========================================\n","class LookThemSTLV1(nn.Module):\n"," def __init__(self):\n"," super(LookThemSTLV1, self).__init__()\n","\n"," #self.register_buffer('grayscale_weights', torch.tensor([0.299, 0.587, 0.114]).view(1, 3, 1, 1))\n","\n"," # --- STREAM A: BENTUK MAKRO ---\n"," self.stream_a = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=2, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 12x12 output\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # Jembatan Progresif Token: Mengompres spasial 256 -> 64 token secara cerdas\n"," #self.token_bridge = nn.Linear(256, 64)\n","\n"," # --- STREAM B: Mikro (?)\n"," self.stream_b = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), # [B, 32, 16, 16]\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 8, 8] (64 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 48x48\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # --- CORE COGNITION LAYER (64 Token, Gabungan Features 32 + 32 = 64) ---\n"," self.lookthemA = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthemB = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthem = LookThemLayer(num_tokens=64, in_features=128, hidden_dim=32)\n","\n"," # -- compressor\n"," self.compressor = nn.AdaptiveAvgPool1d(32)\n","\n","\n"," # --- CLASSIFIER RAMPING ANTI-OVERFIT ---\n"," self.classifier = nn.Sequential(\n"," nn.Flatten(),\n"," nn.Linear(64 * 32, 512),\n"," nn.ReLU(),\n"," nn.Dropout(0.4),\n"," nn.Linear(512, 256),\n"," nn.ReLU(),\n"," nn.Dropout(0.2),\n"," nn.Linear(256, 10)\n"," )\n","\n"," def forward(self, x):\n"," batch_size = x.size(0)\n","\n"," # 1. Ekstrak Stream A (Grayscale 16x16)\n"," #x_gray = torch.sum(x * self.grayscale_weights, dim=1, keepdim=True)\n"," feat_a = self.stream_a(x) # [B, 32, 16, 16]\n"," feat_a_flat = feat_a.view(batch_size, 64, 64)\n"," #feat_a_compressed = self.token_bridge(feat_a_flat) # [B, 32, 64]\n"," feat_a_tokens = feat_a_flat.transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_a_lt = self.lookthemA(feat_a_tokens)\n","\n"," # 2. Ekstrak Stream B (RGB 8x8 via Standard Conv)\n"," feat_b = self.stream_b(x) # [B, 32, 8, 8]\n"," feat_b_tokens = feat_b.view(batch_size, 64, 64).transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_b_lt = self.lookthemB(feat_b_tokens)\n","\n"," # 3. Penggabungan Asimetris Tingkat Features (Total tetap 64 Token)\n"," tokens_combined = torch.cat([feat_a_lt, feat_b_lt], dim=2) # [B, 64 Token, 128 Features]\n","\n"," # 4. Kognisi Relasional & Klasifikasi\n"," out_lookthem = self.lookthem(tokens_combined)\n"," compressed = self.compressor(out_lookthem)\n"," return self.classifier(compressed)\n","\n","# ==========================================\n","# 4. RUNTIME TRAINING + CHECKPOINT SYSTEM\n","# ==========================================\n","device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n","model = LookThemSTLV1().to(device)\n","#model.load_state_dict(torch.load(\"LookThem_STL.pth\"))\n","\n","criterion = nn.CrossEntropyLoss()\n","optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n","scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)\n","\n","start_epoch = 0\n","checkpoint_path = \"lookthem_stl_checkpoint.pth\"\n","\n","if os.path.exists(checkpoint_path):\n"," print(\"πΎ Checkpoint V5 ditemukan! Melanjutkan progres eksperimen...\")\n"," checkpoint = torch.load(checkpoint_path)\n"," model.load_state_dict(checkpoint['model_state_dict'])\n"," optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n"," scheduler.load_state_dict(checkpoint['scheduler_state_dict'])\n"," start_epoch = checkpoint['epoch']\n"," print(f\"βΆοΈ Berhasil resume dari Epoch ke-{start_epoch+1}\")\n","\n","print(f\"π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan {device}...\")\n","\n","for epoch in range(start_epoch, 20):\n"," model.train()\n"," total_loss, correct, total = 0, 0, 0\n","\n"," for data, target in train_loader:\n"," data, target = data.to(device), target.to(device)\n","\n"," optimizer.zero_grad()\n"," output = model(data)\n"," loss = criterion(output, target)\n"," loss.backward()\n"," optimizer.step()\n","\n"," total_loss += loss.item()\n"," _, predicted = output.max(1)\n"," total += target.size(0)\n"," correct += predicted.eq(target).sum().item()\n","\n"," scheduler.step()\n"," acc = 100. * correct / total\n"," current_lr = optimizer.param_groups[0]['lr']\n"," print(f\"Epoch {epoch+1:02d}/45 -> Train Loss: {total_loss/len(train_loader):.4f} | Train Acc: {acc:.2f}% | LR: {current_lr:.6f}\")\n","\n"," if (epoch + 1) % 5 == 0:\n"," torch.save({\n"," 'epoch': epoch + 1,\n"," 'model_state_dict': model.state_dict(),\n"," 'optimizer_state_dict': optimizer.state_dict(),\n"," 'scheduler_state_dict': scheduler.state_dict(),\n"," }, checkpoint_path)\n"," print(f\"π [SYSTEM-SAVER] Progres Epoch {epoch+1} berhasil dikunci ke disk!\")\n","\n","# ==========================================\n","# 5. VALIDASI AKHIR\n","# ==========================================\n","model.eval()\n","test_loss, test_correct, test_total = 0, 0, 0\n","\n","print(\"\\nπ Memulai Pengujian Validasi Akhir...\")\n","with torch.no_grad():\n"," for data, target in val_loader:\n"," data, target = data.to(device), target.to(device)\n"," output = model(data)\n"," loss = criterion(output, target)\n","\n"," test_loss += loss.item()\n"," _, predicted = output.max(1)\n"," test_total += target.size(0)\n"," test_correct += predicted.eq(target).sum().item()\n","\n","final_test_acc = 100. * test_correct / test_total\n","print(\"=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\")\n","print(f\"Test Loss: {test_loss/len(val_loader):.4f} | Test Accuracy: {final_test_acc:.2f}%\")\n","\n","torch.save(model.state_dict(), \"LookThem_STL.pth\")\n","print(f\"π Selesai! Ukuran berkas final: {os.path.getsize('LookThem_STL.pth') / (1024*1024):.2f} MB\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"908ZjmBKSrG4","executionInfo":{"status":"ok","timestamp":1779111688909,"user_tz":-420,"elapsed":144721,"user":{"displayName":"Cici rizky plk","userId":"03714270658772765776"}},"outputId":"90900fc7-d0df-430a-e31b-36046a38f213"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Jumlah data training: 5000\n","Jumlah data testing: 8000\n","π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan cuda...\n","Epoch 01/45 -> Train Loss: 2.1861 | Train Acc: 15.24% | LR: 0.000994\n","Epoch 02/45 -> Train Loss: 1.9006 | Train Acc: 22.18% | LR: 0.000976\n","Epoch 03/45 -> Train Loss: 1.8237 | Train Acc: 26.04% | LR: 0.000946\n","Epoch 04/45 -> Train Loss: 1.7421 | Train Acc: 27.14% | LR: 0.000905\n","Epoch 05/45 -> Train Loss: 1.6598 | Train Acc: 30.34% | LR: 0.000854\n","π [SYSTEM-SAVER] Progres Epoch 5 berhasil dikunci ke disk!\n","Epoch 06/45 -> Train Loss: 1.6362 | Train Acc: 32.38% | LR: 0.000794\n","Epoch 07/45 -> Train Loss: 1.6332 | Train Acc: 31.22% | LR: 0.000727\n","Epoch 08/45 -> Train Loss: 1.6260 | Train Acc: 32.30% | LR: 0.000655\n","Epoch 09/45 -> Train Loss: 1.6186 | Train Acc: 33.64% | LR: 0.000578\n","Epoch 10/45 -> Train Loss: 1.6052 | Train Acc: 34.00% | LR: 0.000500\n","π [SYSTEM-SAVER] Progres Epoch 10 berhasil dikunci ke disk!\n","Epoch 11/45 -> Train Loss: 1.5563 | Train Acc: 36.52% | LR: 0.000422\n","Epoch 12/45 -> Train Loss: 1.4945 | Train Acc: 38.84% | LR: 0.000345\n","Epoch 13/45 -> Train Loss: 1.4635 | Train Acc: 40.64% | LR: 0.000273\n","Epoch 14/45 -> Train Loss: 1.4333 | Train Acc: 42.76% | LR: 0.000206\n","Epoch 15/45 -> Train Loss: 1.3712 | Train Acc: 44.18% | LR: 0.000146\n","π [SYSTEM-SAVER] Progres Epoch 15 berhasil dikunci ke disk!\n","Epoch 16/45 -> Train Loss: 1.3478 | Train Acc: 45.28% | LR: 0.000095\n","Epoch 17/45 -> Train Loss: 1.3604 | Train Acc: 46.70% | LR: 0.000054\n","Epoch 18/45 -> Train Loss: 1.3418 | Train Acc: 46.18% | LR: 0.000024\n","Epoch 19/45 -> Train Loss: 1.3458 | Train Acc: 46.92% | LR: 0.000006\n","Epoch 20/45 -> Train Loss: 1.3322 | Train Acc: 47.04% | LR: 0.000000\n","π [SYSTEM-SAVER] Progres Epoch 20 berhasil dikunci ke disk!\n","\n","π Memulai Pengujian Validasi Akhir...\n","=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\n","Test Loss: 1.3751 | Test Accuracy: 45.84%\n","π Selesai! Ukuran berkas final: 7.79 MB\n"]}]},{"cell_type":"code","source":[],"metadata":{"id":"hRvklh38Uin4"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["import os\n","import zipfile\n","import urllib.request\n","import math\n","import torch\n","import torch.nn as nn\n","import torch.nn.functional as F\n","import torch.optim as optim\n","from torch.utils.data import DataLoader\n","from torchvision import datasets, transforms\n","\n","import torch\n","import torchvision\n","import torchvision.transforms as transforms\n","from torch.utils.data import DataLoader\n","\n","# 1. Atur transformasi (Resize ke target resolusi Anda, misal 128x128 atau 256x256)\n","transform_train = transforms.Compose([\n"," transforms.RandomHorizontalFlip(),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","transform_test = transforms.Compose([\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","# 2. Download dan Load Dataset (Otomatis masuk ke folder ./data)\n","# Ukuran download terkompresi hanya sekitar ~1.9 GB\n","train_dataset = torchvision.datasets.STL10(root='./data', split='train', download=True, transform=transform_train)\n","test_dataset = torchvision.datasets.STL10(root='./data', split='test', download=True, transform=transform_test)\n","\n","# 3. Siapkan DataLoader\n","train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=2)\n","val_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=2)\n","\n","print(f\"Jumlah data training: {len(train_dataset)}\")\n","print(f\"Jumlah data testing: {len(test_dataset)}\")\n","\n","\n","\n","# ==========================================\n","# 2. CORE LAYER: LOOKTHEM CORE LAYER\n","# ==========================================\n","class LookThemLayer(nn.Module):\n"," def __init__(self, num_tokens, in_features, hidden_dim):\n"," super(LookThemLayer, self).__init__()\n"," self.num_tokens = num_tokens\n"," self.in_features = in_features\n","\n"," self.mod1_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod1_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod1_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod1_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.mod2_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod2_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod2_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod2_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.trans_w = nn.Parameter(torch.randn(num_tokens, 1, 1))\n"," self.trans_b = nn.Parameter(torch.zeros(num_tokens, 1))\n"," self._init_weights()\n","\n"," def _init_weights(self):\n"," for w in [self.mod1_w1, self.mod2_w1, self.mod1_w2, self.mod2_w2, self.trans_w]:\n"," nn.init.kaiming_uniform_(w, a=math.sqrt(5))\n","\n"," def forward(self, x):\n"," N = self.num_tokens\n"," h1 = torch.einsum('bti,tij->btj', x, self.mod1_w1) + self.mod1_b1\n"," out_m1 = torch.einsum('btj,tjk->btk', F.gelu(h1), self.mod1_w2) + self.mod1_b2\n","\n"," h2 = torch.einsum('bti,tij->btj', x, self.mod2_w1) + self.mod2_b1\n"," out_m2 = torch.einsum('btj,tjk->btk', F.gelu(h2), self.mod2_w2) + self.mod2_b2\n","\n"," out_m2_safe = out_m2 + 1e-5\n"," compare = torch.tanh(out_m1.unsqueeze(2) / out_m2_safe.unsqueeze(1))\n"," compare2 = torch.tanh(out_m1.unsqueeze(1) / out_m2_safe.unsqueeze(2))\n","\n"," bias_reshaped = self.trans_b.view(1, 1, N, 1)\n"," trans_compare = torch.einsum('bije,jef->bijf', compare, self.trans_w) + bias_reshaped\n"," trans_compare2 = torch.einsum('bije,jef->bijf', compare2, self.trans_w) + bias_reshaped\n","\n"," interaksi = (trans_compare * x.unsqueeze(2) + trans_compare2 * x.unsqueeze(1)) / 2\n"," mask = 1.0 - torch.eye(N, device=x.device)\n"," interaksi_masked = interaksi * mask.view(1, N, N, 1)\n","\n"," return interaksi_masked.sum(dim=2) / (N - 1.0)\n","\n","# ==========================================\n","# 3. INDUK ARSITEKTUR: LOOKTHEM V5 (STANDARD CONV STREAM B)\n","# ==========================================\n","class LookThemSTLV1(nn.Module):\n"," def __init__(self):\n"," super(LookThemSTLV1, self).__init__()\n","\n"," #self.register_buffer('grayscale_weights', torch.tensor([0.299, 0.587, 0.114]).view(1, 3, 1, 1))\n","\n"," # --- STREAM A: BENTUK MAKRO ---\n"," self.stream_a = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=2, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 12x12 output\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # Jembatan Progresif Token: Mengompres spasial 256 -> 64 token secara cerdas\n"," #self.token_bridge = nn.Linear(256, 64)\n","\n"," # --- STREAM B: Mikro (?)\n"," self.stream_b = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), # [B, 32, 16, 16]\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 8, 8] (64 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 48x48\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # --- CORE COGNITION LAYER (64 Token, Gabungan Features 32 + 32 = 64) ---\n"," self.lookthemA = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthemB = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthem = LookThemLayer(num_tokens=64, in_features=128, hidden_dim=32)\n","\n"," # -- compressor\n"," self.compressor = nn.AdaptiveAvgPool1d(32)\n","\n","\n"," # --- CLASSIFIER RAMPING ANTI-OVERFIT ---\n"," self.classifier = nn.Sequential(\n"," nn.Flatten(),\n"," nn.Linear(64 * 32, 512),\n"," nn.ReLU(),\n"," nn.Dropout(0.4),\n"," nn.Linear(512, 256),\n"," nn.ReLU(),\n"," nn.Dropout(0.2),\n"," nn.Linear(256, 10)\n"," )\n","\n"," def forward(self, x):\n"," batch_size = x.size(0)\n","\n"," # 1. Ekstrak Stream A (Grayscale 16x16)\n"," #x_gray = torch.sum(x * self.grayscale_weights, dim=1, keepdim=True)\n"," feat_a = self.stream_a(x) # [B, 32, 16, 16]\n"," feat_a_flat = feat_a.view(batch_size, 64, 64)\n"," #feat_a_compressed = self.token_bridge(feat_a_flat) # [B, 32, 64]\n"," feat_a_tokens = feat_a_flat.transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_a_lt = self.lookthemA(feat_a_tokens)\n","\n"," # 2. Ekstrak Stream B (RGB 8x8 via Standard Conv)\n"," feat_b = self.stream_b(x) # [B, 32, 8, 8]\n"," feat_b_tokens = feat_b.view(batch_size, 64, 64).transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_b_lt = self.lookthemB(feat_b_tokens)\n","\n"," # 3. Penggabungan Asimetris Tingkat Features (Total tetap 64 Token)\n"," tokens_combined = torch.cat([feat_a_lt, feat_b_lt], dim=2) # [B, 64 Token, 128 Features]\n","\n"," # 4. Kognisi Relasional & Klasifikasi\n"," out_lookthem = self.lookthem(tokens_combined)\n"," compressed = self.compressor(out_lookthem)\n"," return self.classifier(compressed)\n","\n","# ==========================================\n","# 4. RUNTIME TRAINING + CHECKPOINT SYSTEM\n","# ==========================================\n","device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n","model = LookThemSTLV1().to(device)\n","#model.load_state_dict(torch.load(\"LookThem_STL.pth\"))\n","\n","criterion = nn.CrossEntropyLoss()\n","optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n","scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=40)\n","\n","start_epoch = 0\n","checkpoint_path = \"lookthem_stl_checkpoint.pth\"\n","\n","if os.path.exists(checkpoint_path):\n"," print(\"πΎ Checkpoint V5 ditemukan! Melanjutkan progres eksperimen...\")\n"," checkpoint = torch.load(checkpoint_path)\n"," model.load_state_dict(checkpoint['model_state_dict'])\n"," optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n"," scheduler.load_state_dict(checkpoint['scheduler_state_dict'])\n"," start_epoch = checkpoint['epoch']\n"," print(f\"βΆοΈ Berhasil resume dari Epoch ke-{start_epoch+1}\")\n","\n","print(f\"π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan {device}...\")\n","\n","for epoch in range(start_epoch, 60):\n"," model.train()\n"," total_loss, correct, total = 0, 0, 0\n","\n"," for data, target in train_loader:\n"," data, target = data.to(device), target.to(device)\n","\n"," optimizer.zero_grad()\n"," output = model(data)\n"," loss = criterion(output, target)\n"," loss.backward()\n"," optimizer.step()\n","\n"," total_loss += loss.item()\n"," _, predicted = output.max(1)\n"," total += target.size(0)\n"," correct += predicted.eq(target).sum().item()\n","\n"," scheduler.step()\n"," acc = 100. * correct / total\n"," current_lr = optimizer.param_groups[0]['lr']\n"," print(f\"Epoch {epoch+1:02d}/45 -> Train Loss: {total_loss/len(train_loader):.4f} | Train Acc: {acc:.2f}% | LR: {current_lr:.6f}\")\n","\n"," if (epoch + 1) % 5 == 0:\n"," torch.save({\n"," 'epoch': epoch + 1,\n"," 'model_state_dict': model.state_dict(),\n"," 'optimizer_state_dict': optimizer.state_dict(),\n"," 'scheduler_state_dict': scheduler.state_dict(),\n"," }, checkpoint_path)\n"," print(f\"π [SYSTEM-SAVER] Progres Epoch {epoch+1} berhasil dikunci ke disk!\")\n","\n","# ==========================================\n","# 5. VALIDASI AKHIR\n","# ==========================================\n","model.eval()\n","test_loss, test_correct, test_total = 0, 0, 0\n","\n","print(\"\\nπ Memulai Pengujian Validasi Akhir...\")\n","with torch.no_grad():\n"," for data, target in val_loader:\n"," data, target = data.to(device), target.to(device)\n"," output = model(data)\n"," loss = criterion(output, target)\n","\n"," test_loss += loss.item()\n"," _, predicted = output.max(1)\n"," test_total += target.size(0)\n"," test_correct += predicted.eq(target).sum().item()\n","\n","final_test_acc = 100. * test_correct / test_total\n","print(\"=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\")\n","print(f\"Test Loss: {test_loss/len(val_loader):.4f} | Test Accuracy: {final_test_acc:.2f}%\")\n","\n","torch.save(model.state_dict(), \"LookThem_STL.pth\")\n","print(f\"π Selesai! Ukuran berkas final: {os.path.getsize('LookThem_STL.pth') / (1024*1024):.2f} MB\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1779112057728,"user_tz":-420,"elapsed":299192,"user":{"displayName":"Cici rizky plk","userId":"03714270658772765776"}},"outputId":"c625aefb-4c7f-4f03-822d-2cc1c81fb01c","id":"H9ueRZmbUkks"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Jumlah data training: 5000\n","Jumlah data testing: 8000\n","πΎ Checkpoint V5 ditemukan! Melanjutkan progres eksperimen...\n","βΆοΈ Berhasil resume dari Epoch ke-21\n","π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan cuda...\n","Epoch 21/45 -> Train Loss: 1.3257 | Train Acc: 47.08% | LR: 0.000006\n","Epoch 22/45 -> Train Loss: 1.3187 | Train Acc: 46.98% | LR: 0.000024\n","Epoch 23/45 -> Train Loss: 1.3258 | Train Acc: 46.28% | LR: 0.000054\n","Epoch 24/45 -> Train Loss: 1.3276 | Train Acc: 47.40% | LR: 0.000095\n","Epoch 25/45 -> Train Loss: 1.3375 | Train Acc: 46.44% | LR: 0.000146\n","π [SYSTEM-SAVER] Progres Epoch 25 berhasil dikunci ke disk!\n","Epoch 26/45 -> Train Loss: 1.3552 | Train Acc: 47.14% | LR: 0.000206\n","Epoch 27/45 -> Train Loss: 1.4293 | Train Acc: 42.12% | LR: 0.000273\n","Epoch 28/45 -> Train Loss: 1.5248 | Train Acc: 37.68% | LR: 0.000345\n","Epoch 29/45 -> Train Loss: 1.4612 | Train Acc: 41.84% | LR: 0.000422\n","Epoch 30/45 -> Train Loss: 1.4173 | Train Acc: 43.16% | LR: 0.000500\n","π [SYSTEM-SAVER] Progres Epoch 30 berhasil dikunci ke disk!\n","Epoch 31/45 -> Train Loss: 1.3478 | Train Acc: 47.20% | LR: 0.000578\n","Epoch 32/45 -> Train Loss: 1.2777 | Train Acc: 51.48% | LR: 0.000655\n","Epoch 33/45 -> Train Loss: 1.2144 | Train Acc: 53.08% | LR: 0.000727\n","Epoch 34/45 -> Train Loss: 1.1731 | Train Acc: 55.56% | LR: 0.000794\n","Epoch 35/45 -> Train Loss: 1.1629 | Train Acc: 55.98% | LR: 0.000854\n","π [SYSTEM-SAVER] Progres Epoch 35 berhasil dikunci ke disk!\n","Epoch 36/45 -> Train Loss: 1.1037 | Train Acc: 57.82% | LR: 0.000905\n","Epoch 37/45 -> Train Loss: 1.0876 | Train Acc: 59.10% | LR: 0.000946\n","Epoch 38/45 -> Train Loss: 1.0291 | Train Acc: 60.94% | LR: 0.000976\n","Epoch 39/45 -> Train Loss: 1.0017 | Train Acc: 62.08% | LR: 0.000994\n","Epoch 40/45 -> Train Loss: 1.0237 | Train Acc: 62.14% | LR: 0.001000\n","π [SYSTEM-SAVER] Progres Epoch 40 berhasil dikunci ke disk!\n","Epoch 41/45 -> Train Loss: 1.3596 | Train Acc: 46.98% | LR: 0.000994\n","Epoch 42/45 -> Train Loss: 1.2626 | Train Acc: 51.54% | LR: 0.000976\n","Epoch 43/45 -> Train Loss: 1.1091 | Train Acc: 57.58% | LR: 0.000946\n","Epoch 44/45 -> Train Loss: 1.0343 | Train Acc: 60.86% | LR: 0.000905\n","Epoch 45/45 -> Train Loss: 0.9551 | Train Acc: 63.86% | LR: 0.000854\n","π [SYSTEM-SAVER] Progres Epoch 45 berhasil dikunci ke disk!\n","Epoch 46/45 -> Train Loss: 0.9094 | Train Acc: 65.92% | LR: 0.000794\n","Epoch 47/45 -> Train Loss: 0.8654 | Train Acc: 67.88% | LR: 0.000727\n","Epoch 48/45 -> Train Loss: 0.9308 | Train Acc: 65.94% | LR: 0.000655\n","Epoch 49/45 -> Train Loss: 0.8748 | Train Acc: 67.72% | LR: 0.000578\n","Epoch 50/45 -> Train Loss: 0.8220 | Train Acc: 70.02% | LR: 0.000500\n","π [SYSTEM-SAVER] Progres Epoch 50 berhasil dikunci ke disk!\n","Epoch 51/45 -> Train Loss: 0.7475 | Train Acc: 72.86% | LR: 0.000422\n","Epoch 52/45 -> Train Loss: 0.7026 | Train Acc: 73.74% | LR: 0.000345\n","Epoch 53/45 -> Train Loss: 0.6936 | Train Acc: 74.84% | LR: 0.000273\n","Epoch 54/45 -> Train Loss: 0.6984 | Train Acc: 74.32% | LR: 0.000206\n","Epoch 55/45 -> Train Loss: 0.6703 | Train Acc: 74.96% | LR: 0.000146\n","π [SYSTEM-SAVER] Progres Epoch 55 berhasil dikunci ke disk!\n","Epoch 56/45 -> Train Loss: 0.7028 | Train Acc: 73.86% | LR: 0.000095\n","Epoch 57/45 -> Train Loss: 1.0392 | Train Acc: 60.72% | LR: 0.000054\n","Epoch 58/45 -> Train Loss: 1.0657 | Train Acc: 60.02% | LR: 0.000024\n","Epoch 59/45 -> Train Loss: 0.9433 | Train Acc: 65.66% | LR: 0.000006\n","Epoch 60/45 -> Train Loss: 0.9097 | Train Acc: 66.76% | LR: 0.000000\n","π [SYSTEM-SAVER] Progres Epoch 60 berhasil dikunci ke disk!\n","\n","π Memulai Pengujian Validasi Akhir...\n","=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\n","Test Loss: 1.0525 | Test Accuracy: 61.85%\n","π Selesai! Ukuran berkas final: 7.79 MB\n"]}]},{"cell_type":"code","source":[],"metadata":{"id":"0QGlj2_MWR3s"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["import os\n","import zipfile\n","import urllib.request\n","import math\n","import torch\n","import torch.nn as nn\n","import torch.nn.functional as F\n","import torch.optim as optim\n","from torch.utils.data import DataLoader\n","from torchvision import datasets, transforms\n","\n","import torch\n","import torchvision\n","import torchvision.transforms as transforms\n","from torch.utils.data import DataLoader\n","\n","# 1. Atur transformasi (Resize ke target resolusi Anda, misal 128x128 atau 256x256)\n","transform_train = transforms.Compose([\n"," transforms.RandomHorizontalFlip(),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","transform_test = transforms.Compose([\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))\n","])\n","\n","# 2. Download dan Load Dataset (Otomatis masuk ke folder ./data)\n","# Ukuran download terkompresi hanya sekitar ~1.9 GB\n","train_dataset = torchvision.datasets.STL10(root='./data', split='train', download=True, transform=transform_train)\n","test_dataset = torchvision.datasets.STL10(root='./data', split='test', download=True, transform=transform_test)\n","\n","# 3. Siapkan DataLoader\n","train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=2)\n","val_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=2)\n","\n","print(f\"Jumlah data training: {len(train_dataset)}\")\n","print(f\"Jumlah data testing: {len(test_dataset)}\")\n","\n","\n","\n","# ==========================================\n","# 2. CORE LAYER: LOOKTHEM CORE LAYER\n","# ==========================================\n","class LookThemLayer(nn.Module):\n"," def __init__(self, num_tokens, in_features, hidden_dim):\n"," super(LookThemLayer, self).__init__()\n"," self.num_tokens = num_tokens\n"," self.in_features = in_features\n","\n"," self.mod1_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod1_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod1_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod1_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.mod2_w1 = nn.Parameter(torch.randn(num_tokens, in_features, hidden_dim))\n"," self.mod2_b1 = nn.Parameter(torch.zeros(num_tokens, hidden_dim))\n"," self.mod2_w2 = nn.Parameter(torch.randn(num_tokens, hidden_dim, 1))\n"," self.mod2_b2 = nn.Parameter(torch.zeros(num_tokens, 1))\n","\n"," self.trans_w = nn.Parameter(torch.randn(num_tokens, 1, 1))\n"," self.trans_b = nn.Parameter(torch.zeros(num_tokens, 1))\n"," self._init_weights()\n","\n"," def _init_weights(self):\n"," for w in [self.mod1_w1, self.mod2_w1, self.mod1_w2, self.mod2_w2, self.trans_w]:\n"," nn.init.kaiming_uniform_(w, a=math.sqrt(5))\n","\n"," def forward(self, x):\n"," N = self.num_tokens\n"," h1 = torch.einsum('bti,tij->btj', x, self.mod1_w1) + self.mod1_b1\n"," out_m1 = torch.einsum('btj,tjk->btk', F.gelu(h1), self.mod1_w2) + self.mod1_b2\n","\n"," h2 = torch.einsum('bti,tij->btj', x, self.mod2_w1) + self.mod2_b1\n"," out_m2 = torch.einsum('btj,tjk->btk', F.gelu(h2), self.mod2_w2) + self.mod2_b2\n","\n"," out_m2_safe = out_m2 + 1e-5\n"," compare = torch.tanh(out_m1.unsqueeze(2) / out_m2_safe.unsqueeze(1))\n"," compare2 = torch.tanh(out_m1.unsqueeze(1) / out_m2_safe.unsqueeze(2))\n","\n"," bias_reshaped = self.trans_b.view(1, 1, N, 1)\n"," trans_compare = torch.einsum('bije,jef->bijf', compare, self.trans_w) + bias_reshaped\n"," trans_compare2 = torch.einsum('bije,jef->bijf', compare2, self.trans_w) + bias_reshaped\n","\n"," interaksi = (trans_compare * x.unsqueeze(2) + trans_compare2 * x.unsqueeze(1)) / 2\n"," mask = 1.0 - torch.eye(N, device=x.device)\n"," interaksi_masked = interaksi * mask.view(1, N, N, 1)\n","\n"," return interaksi_masked.sum(dim=2) / (N - 1.0)\n","\n","# ==========================================\n","# 3. INDUK ARSITEKTUR: LOOKTHEM V5 (STANDARD CONV STREAM B)\n","# ==========================================\n","class LookThemSTLV1(nn.Module):\n"," def __init__(self):\n"," super(LookThemSTLV1, self).__init__()\n","\n"," #self.register_buffer('grayscale_weights', torch.tensor([0.299, 0.587, 0.114]).view(1, 3, 1, 1))\n","\n"," # --- STREAM A: BENTUK MAKRO ---\n"," self.stream_a = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=2, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 16, 16] (256 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 12x12 output\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # Jembatan Progresif Token: Mengompres spasial 256 -> 64 token secara cerdas\n"," #self.token_bridge = nn.Linear(256, 64)\n","\n"," # --- STREAM B: Mikro (?)\n"," self.stream_b = nn.Sequential(\n"," nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), # [B, 16, 32, 32]\n"," nn.BatchNorm2d(16), nn.GELU(),\n"," nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), # [B, 32, 16, 16]\n"," nn.BatchNorm2d(32), nn.GELU(),\n"," nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # [B, 32, 8, 8] (64 Luas Spasial)\n"," nn.BatchNorm2d(64), nn.GELU(), # 48x48\n"," nn.AdaptiveMaxPool2d((8, 8))\n"," )\n","\n"," # --- CORE COGNITION LAYER (64 Token, Gabungan Features 32 + 32 = 64) ---\n"," self.lookthemA = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthemB = LookThemLayer(num_tokens=64, in_features=64, hidden_dim=16)\n"," self.lookthem = LookThemLayer(num_tokens=64, in_features=128, hidden_dim=32)\n","\n"," # -- compressor\n"," self.compressor = nn.AdaptiveAvgPool1d(32)\n","\n","\n"," # --- CLASSIFIER RAMPING ANTI-OVERFIT ---\n"," self.classifier = nn.Sequential(\n"," nn.Flatten(),\n"," nn.Linear(64 * 32, 512),\n"," nn.ReLU(),\n"," nn.Dropout(0.4),\n"," nn.Linear(512, 256),\n"," nn.ReLU(),\n"," nn.Dropout(0.2),\n"," nn.Linear(256, 10)\n"," )\n","\n"," def forward(self, x):\n"," batch_size = x.size(0)\n","\n"," # 1. Ekstrak Stream A (Grayscale 16x16)\n"," #x_gray = torch.sum(x * self.grayscale_weights, dim=1, keepdim=True)\n"," feat_a = self.stream_a(x) # [B, 32, 16, 16]\n"," feat_a_flat = feat_a.view(batch_size, 64, 64)\n"," #feat_a_compressed = self.token_bridge(feat_a_flat) # [B, 32, 64]\n"," feat_a_tokens = feat_a_flat.transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_a_lt = self.lookthemA(feat_a_tokens)\n","\n"," # 2. Ekstrak Stream B (RGB 8x8 via Standard Conv)\n"," feat_b = self.stream_b(x) # [B, 32, 8, 8]\n"," feat_b_tokens = feat_b.view(batch_size, 64, 64).transpose(1, 2) # [B, 64 Token, 32 Features]\n"," feat_b_lt = self.lookthemB(feat_b_tokens)\n","\n"," # 3. Penggabungan Asimetris Tingkat Features (Total tetap 64 Token)\n"," tokens_combined = torch.cat([feat_a_lt, feat_b_lt], dim=2) # [B, 64 Token, 128 Features]\n","\n"," # 4. Kognisi Relasional & Klasifikasi\n"," out_lookthem = self.lookthem(tokens_combined)\n"," compressed = self.compressor(out_lookthem)\n"," return self.classifier(compressed)\n","\n","# ==========================================\n","# 4. RUNTIME TRAINING + CHECKPOINT SYSTEM\n","# ==========================================\n","device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n","model = LookThemSTLV1().to(device)\n","#model.load_state_dict(torch.load(\"LookThem_STL.pth\"))\n","\n","criterion = nn.CrossEntropyLoss()\n","optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n","scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=40)\n","\n","start_epoch = 0\n","checkpoint_path = \"lookthem_stl_checkpoint.pth\"\n","\n","if os.path.exists(checkpoint_path):\n"," print(\"πΎ Checkpoint V5 ditemukan! Melanjutkan progres eksperimen...\")\n"," checkpoint = torch.load(checkpoint_path)\n"," model.load_state_dict(checkpoint['model_state_dict'])\n"," optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n"," scheduler.load_state_dict(checkpoint['scheduler_state_dict'])\n"," start_epoch = checkpoint['epoch']\n"," print(f\"βΆοΈ Berhasil resume dari Epoch ke-{start_epoch+1}\")\n","\n","print(f\"π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan {device}...\")\n","\n","for epoch in range(start_epoch, 100):\n"," model.train()\n"," total_loss, correct, total = 0, 0, 0\n","\n"," for data, target in train_loader:\n"," data, target = data.to(device), target.to(device)\n","\n"," optimizer.zero_grad()\n"," output = model(data)\n"," loss = criterion(output, target)\n"," loss.backward()\n"," optimizer.step()\n","\n"," total_loss += loss.item()\n"," _, predicted = output.max(1)\n"," total += target.size(0)\n"," correct += predicted.eq(target).sum().item()\n","\n"," scheduler.step()\n"," acc = 100. * correct / total\n"," current_lr = optimizer.param_groups[0]['lr']\n"," print(f\"Epoch {epoch+1:02d}/45 -> Train Loss: {total_loss/len(train_loader):.4f} | Train Acc: {acc:.2f}% | LR: {current_lr:.6f}\")\n","\n"," if (epoch + 1) % 5 == 0:\n"," torch.save({\n"," 'epoch': epoch + 1,\n"," 'model_state_dict': model.state_dict(),\n"," 'optimizer_state_dict': optimizer.state_dict(),\n"," 'scheduler_state_dict': scheduler.state_dict(),\n"," }, checkpoint_path)\n"," print(f\"π [SYSTEM-SAVER] Progres Epoch {epoch+1} berhasil dikunci ke disk!\")\n","\n","# ==========================================\n","# 5. VALIDASI AKHIR\n","# ==========================================\n","model.eval()\n","test_loss, test_correct, test_total = 0, 0, 0\n","\n","print(\"\\nπ Memulai Pengujian Validasi Akhir...\")\n","with torch.no_grad():\n"," for data, target in val_loader:\n"," data, target = data.to(device), target.to(device)\n"," output = model(data)\n"," loss = criterion(output, target)\n","\n"," test_loss += loss.item()\n"," _, predicted = output.max(1)\n"," test_total += target.size(0)\n"," test_correct += predicted.eq(target).sum().item()\n","\n","final_test_acc = 100. * test_correct / test_total\n","print(\"=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\")\n","print(f\"Test Loss: {test_loss/len(val_loader):.4f} | Test Accuracy: {final_test_acc:.2f}%\")\n","\n","torch.save(model.state_dict(), \"LookThem_STL.pth\")\n","print(f\"π Selesai! Ukuran berkas final: {os.path.getsize('LookThem_STL.pth') / (1024*1024):.2f} MB\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1779112478827,"user_tz":-420,"elapsed":291124,"user":{"displayName":"Cici rizky plk","userId":"03714270658772765776"}},"outputId":"8c3cc68a-2d13-4596-af9d-9b6661839f17","id":"iL64jpBvWTuQ"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Jumlah data training: 5000\n","Jumlah data testing: 8000\n","πΎ Checkpoint V5 ditemukan! Melanjutkan progres eksperimen...\n","βΆοΈ Berhasil resume dari Epoch ke-61\n","π Memulai pengujian LookThem V5 (Asymmetric Fusion) menggunakan cuda...\n","Epoch 61/45 -> Train Loss: 0.9089 | Train Acc: 66.52% | LR: 0.000006\n","Epoch 62/45 -> Train Loss: 0.9215 | Train Acc: 67.04% | LR: 0.000024\n","Epoch 63/45 -> Train Loss: 0.8922 | Train Acc: 67.52% | LR: 0.000054\n","Epoch 64/45 -> Train Loss: 0.8708 | Train Acc: 67.60% | LR: 0.000095\n","Epoch 65/45 -> Train Loss: 0.8280 | Train Acc: 69.62% | LR: 0.000146\n","π [SYSTEM-SAVER] Progres Epoch 65 berhasil dikunci ke disk!\n","Epoch 66/45 -> Train Loss: 0.7995 | Train Acc: 70.16% | LR: 0.000206\n","Epoch 67/45 -> Train Loss: 0.7859 | Train Acc: 71.62% | LR: 0.000273\n","Epoch 68/45 -> Train Loss: 0.8199 | Train Acc: 70.12% | LR: 0.000345\n","Epoch 69/45 -> Train Loss: 1.0853 | Train Acc: 59.98% | LR: 0.000422\n","Epoch 70/45 -> Train Loss: 0.8992 | Train Acc: 67.18% | LR: 0.000500\n","π [SYSTEM-SAVER] Progres Epoch 70 berhasil dikunci ke disk!\n","Epoch 71/45 -> Train Loss: 0.8329 | Train Acc: 69.24% | LR: 0.000578\n","Epoch 72/45 -> Train Loss: 0.8091 | Train Acc: 70.52% | LR: 0.000655\n","Epoch 73/45 -> Train Loss: 0.7831 | Train Acc: 70.86% | LR: 0.000727\n","Epoch 74/45 -> Train Loss: 0.7324 | Train Acc: 72.78% | LR: 0.000794\n","Epoch 75/45 -> Train Loss: 0.7404 | Train Acc: 72.24% | LR: 0.000854\n","π [SYSTEM-SAVER] Progres Epoch 75 berhasil dikunci ke disk!\n","Epoch 76/45 -> Train Loss: 0.7374 | Train Acc: 72.82% | LR: 0.000905\n","Epoch 77/45 -> Train Loss: 0.7664 | Train Acc: 71.96% | LR: 0.000946\n","Epoch 78/45 -> Train Loss: 0.7607 | Train Acc: 72.78% | LR: 0.000976\n","Epoch 79/45 -> Train Loss: 0.7387 | Train Acc: 72.70% | LR: 0.000994\n","Epoch 80/45 -> Train Loss: 0.7153 | Train Acc: 73.82% | LR: 0.001000\n","π [SYSTEM-SAVER] Progres Epoch 80 berhasil dikunci ke disk!\n","Epoch 81/45 -> Train Loss: 0.6783 | Train Acc: 74.38% | LR: 0.000994\n","Epoch 82/45 -> Train Loss: 0.6786 | Train Acc: 75.24% | LR: 0.000976\n","Epoch 83/45 -> Train Loss: 0.6519 | Train Acc: 76.56% | LR: 0.000946\n","Epoch 84/45 -> Train Loss: 0.7107 | Train Acc: 74.04% | LR: 0.000905\n","Epoch 85/45 -> Train Loss: 0.6512 | Train Acc: 76.58% | LR: 0.000854\n","π [SYSTEM-SAVER] Progres Epoch 85 berhasil dikunci ke disk!\n","Epoch 86/45 -> Train Loss: 0.6872 | Train Acc: 74.86% | LR: 0.000794\n","Epoch 87/45 -> Train Loss: 0.7050 | Train Acc: 73.66% | LR: 0.000727\n","Epoch 88/45 -> Train Loss: 0.7787 | Train Acc: 71.18% | LR: 0.000655\n","Epoch 89/45 -> Train Loss: 0.6088 | Train Acc: 77.98% | LR: 0.000578\n","Epoch 90/45 -> Train Loss: 0.5411 | Train Acc: 80.90% | LR: 0.000500\n","π [SYSTEM-SAVER] Progres Epoch 90 berhasil dikunci ke disk!\n","Epoch 91/45 -> Train Loss: 0.4962 | Train Acc: 81.62% | LR: 0.000422\n","Epoch 92/45 -> Train Loss: 0.5020 | Train Acc: 81.92% | LR: 0.000345\n","Epoch 93/45 -> Train Loss: 0.4734 | Train Acc: 83.02% | LR: 0.000273\n","Epoch 94/45 -> Train Loss: 0.4814 | Train Acc: 82.38% | LR: 0.000206\n","Epoch 95/45 -> Train Loss: 0.4563 | Train Acc: 83.88% | LR: 0.000146\n","π [SYSTEM-SAVER] Progres Epoch 95 berhasil dikunci ke disk!\n","Epoch 96/45 -> Train Loss: 0.4491 | Train Acc: 83.62% | LR: 0.000095\n","Epoch 97/45 -> Train Loss: 0.4535 | Train Acc: 84.04% | LR: 0.000054\n","Epoch 98/45 -> Train Loss: 0.4753 | Train Acc: 83.34% | LR: 0.000024\n","Epoch 99/45 -> Train Loss: 0.4828 | Train Acc: 82.78% | LR: 0.000006\n","Epoch 100/45 -> Train Loss: 0.4859 | Train Acc: 82.24% | LR: 0.000000\n","π [SYSTEM-SAVER] Progres Epoch 100 berhasil dikunci ke disk!\n","\n","π Memulai Pengujian Validasi Akhir...\n","=== HASIL EVALUASI AKHIR LOOKTHEM V5 ===\n","Test Loss: 0.8978 | Test Accuracy: 69.76%\n","π Selesai! Ukuran berkas final: 7.79 MB\n"]}]}]}
|
LookThem_STL.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:97e08a1fa2f207e09d224a9eb011e8fa411705ed96751d699c229052243a07c4
|
| 3 |
+
size 8164637
|