MamaPearl commited on
Commit
398573a
·
verified ·
1 Parent(s): 65cec23

Update train.py

Browse files
Files changed (1) hide show
  1. train.py +82 -134
train.py CHANGED
@@ -1,155 +1,103 @@
1
- from datasets import load_dataset
2
- import torchvision.transforms as T
3
- from torch.utils.data import Dataset, DataLoader
4
- from PIL import Image
5
  from tqdm.auto import tqdm
6
-
7
- dataset = load_dataset("uoft-cs/cifar10")
8
- train_transform = T.Compose([
9
- T.RandomCrop(32, padding=4),
10
- T.RandomHorizontalFlip(p=0.5),
11
- T.AutoAugment(policy=T.AutoAugmentPolicy.CIFAR10),
12
- T.ToTensor(),
13
- T.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
14
- ])
15
- test_transform = T.Compose([
16
- T.ToTensor(),
17
- T.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
18
- ])
19
-
20
- class CIFAR10Wrapper(Dataset):
21
- def __init__(self, hf_ds, transform):
22
- self.ds = hf_ds
23
- self.transform = transform
24
-
25
- def __len__(self):
26
- return len(self.ds)
27
-
28
- def __getitem__(self, i):
29
- ex = self.ds[i]
30
- img = ex["img"]
31
- label = ex["label"]
32
-
33
- if not isinstance(img, Image.Image):
34
- img = Image.fromarray(img)
35
- x = self.transform(img)
36
- return { "pixel_values": x, "labels": label }
37
-
38
- train_ds = CIFAR10Wrapper(dataset["train"], train_transform)
39
- test_ds = CIFAR10Wrapper(dataset["test"], test_transform)
40
-
41
- train_loader = DataLoader(
42
- train_ds,
43
- batch_size=128,
44
- shuffle=True,
45
- num_workers=0,
46
- pin_memory=True
47
- )
48
-
49
- test_loader = DataLoader(
50
- test_ds,
51
- batch_size=256,
52
- shuffle=False,
53
- num_workers=0,
54
- pin_memory=True
55
- )
56
-
57
- batch = next(iter(train_loader))
58
- print(batch["pixel_values"].shape)
59
- print(batch['labels'].shape)
60
- from torch.optim.lr_scheduler import SequentialLR, LinearLR, CosineAnnealingLR
61
-
62
- cfg = NulaConfig(
63
- block_channels=(128, 256, 512),
64
- classifier_hidden_dim=512,
65
- use_se=True
66
- )
67
-
68
- DEVICE = "cuda" if pt.cuda.is_available() else "cpu"
69
- model = NulaForImageClassification(cfg).to(DEVICE)
70
-
71
- optimizer = pt.optim.AdamW(
72
- model.parameters(),
73
- lr=1e-3,
74
- weight_decay=0.01
75
- )
76
- warmup = LinearLR(optimizer, start_factor=0.1, end_factor=1.0, total_iters=5)
77
- cosine = CosineAnnealingLR(optimizer, T_max=45)
78
- scheduler = SequentialLR(optimizer, schedulers=[warmup, cosine], milestones=[5])
79
-
80
- def train_one_epoch(model, loader, optimizer, device, grad_clip=1.0):
81
  model.train()
82
-
83
- total_loss = 0.0
84
- total_correct = 0
85
- total_examples = 0
86
-
87
- pbar = tqdm(loader, desc="training...", leave=False)
88
-
89
  for batch in pbar:
90
  x = batch["pixel_values"].to(device, non_blocking=True)
91
  y = batch["labels"].to(device, non_blocking=True)
92
  optimizer.zero_grad(set_to_none=True)
93
-
94
- out = model(pixel_values=x, labels=y)
95
- loss = out.loss
96
- logits = out.logits
97
- preds = logits.argmax(dim=1)
98
-
99
- loss.backward()
100
- pt.nn.utils.clip_grad_norm_(model.parameters(), grad_clip)
101
- optimizer.step()
102
  total_loss += loss.item() * y.size(0)
103
-
104
- total_correct += (preds == y).sum().item()
105
  total_examples += y.size(0)
106
-
107
  pbar.set_postfix(loss=f"{loss.item():.4f}", acc=f"{100 * total_correct / total_examples:.2f}%")
108
  return total_loss / total_examples, total_correct / total_examples
109
 
110
  @pt.no_grad()
111
  def evaluate(model, loader, device):
112
  model.eval()
113
- total_loss = 0.0
114
- total_correct = 0
115
- total_examples = 0
116
-
117
  for batch in loader:
118
  x = batch["pixel_values"].to(device, non_blocking=True)
119
  y = batch["labels"].to(device, non_blocking=True)
120
-
121
  out = model(pixel_values=x, labels=y)
122
- loss = out.loss
123
- logits = out.logits
124
- preds = logits.argmax(dim=1)
125
-
126
- total_loss += loss.item() * y.size(0)
127
- total_correct += (preds == y).sum().item()
128
  total_examples += y.size(0)
129
  return total_loss / total_examples, total_correct / total_examples
130
 
131
- num_epochs = 50
132
- best_val_acc = 0.0
133
- best_epoch = 0
134
-
135
- for epoch in range(1, num_epochs + 1):
136
- train_loss, train_acc = train_one_epoch(model, train_loader, optimizer, DEVICE)
137
- val_loss, val_acc = evaluate(model, test_loader, DEVICE)
138
- scheduler.step()
139
-
140
- if val_acc > best_val_acc:
141
- best_val_acc = val_acc
142
- best_epoch = epoch
143
- if epoch > 10:
144
- model.save_pretrained("./nula-best-temp")
145
- print(f"Saved new best weights (Epoch {epoch})")
146
-
147
- current_lr = optimizer.param_groups[0]["lr"]
148
- print(f"{'='}{'-'*60}{'='}")
149
- print(f"Epoch [{epoch}/{num_epochs}]")
150
- print(f"learning_rate : {current_lr:.6f}")
151
- print(f"train_loss : {train_loss:.6f}")
152
- print(f"train_acc : {train_acc * 100:.2f}%")
153
- print(f"val_loss : {val_loss:.4f}")
154
- print(f"val_acc : {val_acc * 100:.2f}%")
155
- print(f"best_val_acc : {100 * best_val_acc:.2f}% (epoch {best_epoch})")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch as pt
3
+ from torch.amp import autocast, GradScaler
4
+ from torch.optim.lr_scheduler import LinearLR, CosineAnnealingLR, SequentialLR
5
  from tqdm.auto import tqdm
6
+ from safetensors.torch import load_file
7
+ from src.configuration_nula import NulaConfig
8
+ from src.modeling_nula import NulaForImageClassification
9
+ from src.dataset import get_loaders, get_device
10
+
11
+ NUM_EPOCHS = 50
12
+ LR = 1e-3
13
+ WEIGHT_DECAY = 0.01
14
+ WARMUP_STEPS = 5
15
+ GRAD_CLIP = 1.0
16
+ SAVE_EVERY = 5
17
+ CHECKPOINT_DIR = "./checkpoints"
18
+ BEST_MODEL_DIR = "./nula-best-model"
19
+ FINAL_MODEL_DIR = "./nula-final-model"
20
+
21
+ def train_epoch(model, loader, optimizer, scaler, device, epoch):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  model.train()
23
+ total_loss, total_correct, total_examples = 0.0, 0, 0
24
+ pbar = tqdm(loader, desc=f"epoch {epoch}", leave=False)
 
 
 
 
 
25
  for batch in pbar:
26
  x = batch["pixel_values"].to(device, non_blocking=True)
27
  y = batch["labels"].to(device, non_blocking=True)
28
  optimizer.zero_grad(set_to_none=True)
29
+ with autocast("cuda"):
30
+ out = model(pixel_values=x, labels=y)
31
+ loss = out.loss
32
+ scaler.scale(loss).backward()
33
+ scaler.unscale_(optimizer)
34
+ pt.nn.utils.clip_grad_norm_(model.parameters(), max_norm=GRAD_CLIP)
35
+ scaler.step(optimizer)
36
+ scaler.update()
 
37
  total_loss += loss.item() * y.size(0)
38
+ total_correct += (out.logits.argmax(dim=1) == y).sum().item()
 
39
  total_examples += y.size(0)
 
40
  pbar.set_postfix(loss=f"{loss.item():.4f}", acc=f"{100 * total_correct / total_examples:.2f}%")
41
  return total_loss / total_examples, total_correct / total_examples
42
 
43
  @pt.no_grad()
44
  def evaluate(model, loader, device):
45
  model.eval()
46
+ total_loss, total_correct, total_examples = 0.0, 0, 0
 
 
 
47
  for batch in loader:
48
  x = batch["pixel_values"].to(device, non_blocking=True)
49
  y = batch["labels"].to(device, non_blocking=True)
 
50
  out = model(pixel_values=x, labels=y)
51
+ total_loss += out.loss.item() * y.size(0)
52
+ total_correct += (out.logits.argmax(dim=1) == y).sum().item()
 
 
 
 
53
  total_examples += y.size(0)
54
  return total_loss / total_examples, total_correct / total_examples
55
 
56
+ def train_model(model, train_loader, test_loader, optimizer, scheduler, scaler, device):
57
+ best_val_acc = 0.0
58
+ os.makedirs(CHECKPOINT_DIR, exist_ok=True)
59
+
60
+ print(f"training on {device}")
61
+ for epoch in range(1, NUM_EPOCHS + 1):
62
+ train_loss, train_acc = train_epoch(model, train_loader, optimizer, scaler, device, epoch)
63
+ val_loss, val_acc = evaluate(model, test_loader, device)
64
+ scheduler.step()
65
+
66
+ if epoch % SAVE_EVERY == 0:
67
+ save_path = f"{CHECKPOINT_DIR}/epoch{epoch}"
68
+ model.save_pretrained(save_path)
69
+
70
+ if val_acc > best_val_acc:
71
+ best_val_acc = val_acc
72
+ model.save_pretrained(BEST_MODEL_DIR)
73
+ print(f"new best: {100 * best_val_acc:.2f}%")
74
+
75
+ current_lr = optimizer.param_groups[0]["lr"]
76
+ print(f"={'—'*60}=")
77
+ print(f"epoch [{epoch}/{NUM_EPOCHS}]")
78
+ print(f"lr: {current_lr:.6f}")
79
+ print(f"train_loss: {train_loss:.4f}")
80
+ print(f"train_acc: {train_acc*100:.2f}%")
81
+ print(f"val loss: {val_loss:.4f}")
82
+ print(f"val_acc: {val_acc*100:.2f}%")
83
+ print(f"best: {best_val_acc*100:.2f}%")
84
+
85
+ model.save_pretrained(FINAL_MODEL_DIR)
86
+ print("final model saved")
87
+
88
+
89
+ if __name__ == "__main__":
90
+ DEVICE = get_device()
91
+ train_loader, test_loader = get_loaders()
92
+
93
+ cfg = NulaConfig(block_channels=(128, 256, 512), classifier_hidden_dim=512, use_se=True)
94
+ model = NulaForImageClassification(cfg).to(DEVICE)
95
+
96
+ optimizer = pt.optim.AdamW(model.parameters(), lr=LR, weight_decay=WEIGHT_DECAY)
97
+ warmup = LinearLR(optimizer, start_factor=0.1, end_factor=1.0, total_iters=WARMUP_STEPS)
98
+ cosine = CosineAnnealingLR(optimizer, T_max=NUM_EPOCHS - WARMUP_STEPS)
99
+ scheduler = SequentialLR(optimizer, schedulers=[warmup, cosine], milestones=[WARMUP_STEPS])
100
+ scaler = GradScaler("cuda")
101
+
102
+ print("enjoy <3\n")
103
+ train_model(model, train_loader, test_loader, optimizer, scheduler, scaler, DEVICE)