Shanmuk4622 commited on
Commit
b7032a0
·
verified ·
1 Parent(s): 739cb20

Upload test3/eden_UNet_CIFAR10.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. test3/eden_UNet_CIFAR10.py +157 -0
test3/eden_UNet_CIFAR10.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.optim as optim
4
+ import torchvision
5
+ import torchvision.transforms as transforms
6
+ from torch.utils.data import DataLoader, TensorDataset
7
+ from sklearn.metrics import f1_score, precision_score, recall_score
8
+ from codecarbon import EmissionsTracker
9
+ from thop import profile
10
+ from tqdm import tqdm
11
+ import time, pandas as pd, numpy as np, os, warnings, copy, gc
12
+
13
+ # --- Configuration ---
14
+ MODEL_NAME = "unet_classifier_EDEN"
15
+ DATASET_NAME = "CIFAR10"
16
+ DATA_PATH = r'C:\Users\shanm\Dataset Download\CIFAR10'
17
+ BATCH_SIZE = 64
18
+ ACCUMULATION_STEPS = 8 # Effective Batch Size = 512
19
+ EPOCHS = 20
20
+ E_UNFREEZE = 10
21
+ LAMBDA_L1 = 1e-5
22
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
+
24
+ SAVE_DIR = "saved_models"
25
+ os.makedirs(SAVE_DIR, exist_ok=True)
26
+ CSV_FILENAME = f"{MODEL_NAME}_{DATASET_NAME}_stats.csv"
27
+
28
+ warnings.filterwarnings("ignore")
29
+ os.environ["CODECARBON_LOG_LEVEL"] = "error"
30
+
31
+ # --- U-Net Adaptation for Classification ---
32
+ class UNetClassifier(nn.Module):
33
+ def __init__(self, num_classes=10):
34
+ super(UNetClassifier, self).__init__()
35
+ # Using ResNet18 as the backbone for the U-Net Encoder
36
+ self.backbone = torchvision.models.resnet18(weights='IMAGENET1K_V1')
37
+ self.encoder = nn.Sequential(*list(self.backbone.children())[:-2])
38
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
39
+ self.classifier = nn.Linear(512, num_classes)
40
+
41
+ def forward(self, x):
42
+ x = self.encoder(x)
43
+ x = self.avgpool(x)
44
+ x = torch.flatten(x, 1)
45
+ x = self.classifier(x)
46
+ return x
47
+
48
+ def main():
49
+ # --- Phase 1: Zero-Overhead RAM Caching ---
50
+ transform = transforms.Compose([
51
+ transforms.Resize(224),
52
+ transforms.ToTensor(),
53
+ transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
54
+ ])
55
+
56
+ print(f"[*] Caching {DATASET_NAME} to System RAM...")
57
+ full_dataset = torchvision.datasets.CIFAR10(root=DATA_PATH, train=True, download=False, transform=transform)
58
+
59
+ all_data, all_targets = [], []
60
+ for i, (img, target) in enumerate(full_dataset):
61
+ all_data.append(img)
62
+ all_targets.append(target)
63
+ if i % 10000 == 0: print(f" Loaded {i}/50000 images...")
64
+
65
+ cached_trainset = TensorDataset(torch.stack(all_data), torch.tensor(all_targets))
66
+ trainloader = DataLoader(cached_trainset, batch_size=BATCH_SIZE, shuffle=True, pin_memory=True)
67
+
68
+ # --- Model Setup ---
69
+ model = UNetClassifier(num_classes=10)
70
+
71
+ # 1. Profile on clone to avoid hook error
72
+ print("[*] Calculating hardware metrics...")
73
+ model_for_profile = copy.deepcopy(model).to(DEVICE)
74
+ dummy_input = torch.randn(1, 3, 224, 224).to(DEVICE)
75
+ flops, params = profile(model_for_profile, inputs=(dummy_input, ), verbose=False)
76
+ del model_for_profile
77
+
78
+ # 2. Freeze encoder
79
+ for param in model.encoder.parameters():
80
+ param.requires_grad = False
81
+ model.to(DEVICE)
82
+
83
+ criterion = nn.CrossEntropyLoss()
84
+ optimizer = optim.AdamW(model.parameters(), lr=1e-3)
85
+ scaler = torch.cuda.amp.GradScaler()
86
+ tracker = EmissionsTracker(measure_power_secs=1, save_to_file=False, log_level='error')
87
+
88
+ results = []
89
+ cumulative_total_energy = 0
90
+ best_acc = 0.0
91
+
92
+ print(f"\n[MODEL INFO] FLOPs: {flops/1e9:.2f} G | Parameters: {params/1e6:.2f} M")
93
+ print(f"{'='*140}")
94
+ print(f"{'Epoch':<6} | {'Loss':<7} | {'Acc':<7} | {'Total(J)':<9} | {'VRAM(GB)':<9} | {'EAG':<8} | {'Status'}")
95
+ print(f"{'-'*140}")
96
+
97
+ for epoch in range(1, EPOCHS + 1):
98
+ if epoch == E_UNFREEZE:
99
+ for param in model.parameters(): param.requires_grad = True
100
+ for pg in optimizer.param_groups: pg['lr'] = 1e-5
101
+ status_msg = "UNFROZEN"
102
+ else:
103
+ status_msg = "FROZEN" if epoch < E_UNFREEZE else "FINE-TUNING"
104
+
105
+ model.train()
106
+ tracker.start()
107
+ epoch_start = time.time()
108
+ running_loss, all_preds, all_labels = 0.0, [], []
109
+
110
+ pbar = tqdm(enumerate(trainloader), total=len(trainloader), desc=f"Epoch {epoch:02d}", leave=False)
111
+
112
+ optimizer.zero_grad()
113
+ for i, (inputs, labels) in pbar:
114
+ inputs, labels = inputs.to(DEVICE), labels.to(DEVICE)
115
+ with torch.cuda.amp.autocast():
116
+ outputs = model(inputs)
117
+ cls_loss = criterion(outputs, labels)
118
+ l1_penalty = sum(p.abs().sum() for p in model.parameters() if p.requires_grad)
119
+ loss = (cls_loss + LAMBDA_L1 * l1_penalty) / ACCUMULATION_STEPS
120
+
121
+ scaler.scale(loss).backward()
122
+ if (i + 1) % ACCUMULATION_STEPS == 0:
123
+ scaler.unscale_(optimizer)
124
+ torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
125
+ scaler.step(optimizer); scaler.update(); optimizer.zero_grad()
126
+
127
+ running_loss += cls_loss.item()
128
+ _, predicted = torch.max(outputs.data, 1)
129
+ all_preds.extend(predicted.cpu().numpy()); all_labels.extend(labels.cpu().numpy())
130
+ pbar.set_postfix({'loss': f"{cls_loss.item():.4f}"})
131
+
132
+ emissions_kg = tracker.stop()
133
+ duration = time.time() - epoch_start
134
+ e_tot = (tracker.final_emissions_data.gpu_energy + tracker.final_emissions_data.cpu_energy + tracker.final_emissions_data.ram_energy) * 3600000
135
+ cumulative_total_energy += e_tot
136
+ acc = (np.array(all_preds) == np.array(all_labels)).mean()
137
+ vram_peak = torch.cuda.max_memory_allocated(DEVICE) / (1024**3)
138
+ eag = acc / (e_tot / 1000) if e_tot > 0 else 0
139
+
140
+ stats = {
141
+ "epoch": epoch, "status": status_msg, "loss": running_loss / len(trainloader),
142
+ "accuracy": acc, "total_energy_j": e_tot, "cumulative_energy_j": cumulative_total_energy,
143
+ "vram_gb": vram_peak, "eag_metric": eag, "carbon_kg": emissions_kg,
144
+ "model_flops": flops, "model_params": params
145
+ }
146
+ results.append(stats)
147
+ pd.DataFrame(results).to_csv(CSV_FILENAME, index=False)
148
+
149
+ best_tag = "*" if acc > best_acc else ""
150
+ if acc > best_acc: best_acc = acc; torch.save(model.state_dict(), os.path.join(SAVE_DIR, f"BEST_{MODEL_NAME}_{DATASET_NAME}.pth"))
151
+ print(f"{epoch:02d}/50 | {stats['loss']:.4f} | {acc:.2%} | {e_tot:<9.2f} | {vram_peak:<9.3f} | {eag:<8.4f} | {status_msg}{best_tag}")
152
+
153
+ del model, trainloader, cached_trainset
154
+ torch.cuda.empty_cache(); gc.collect()
155
+
156
+ if __name__ == '__main__':
157
+ main()