In [1]:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, random_split
from tqdm import tqdm

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
In [2]:
transforms_classic = transforms.Compose([
    transforms.Pad(2),
    transforms.ToTensor(),
    transforms.Normalize(0.5, 0.5)
])

train_dataset = datasets.FashionMNIST(root='./data', train=True, transform=transforms_classic, download=True)
test_dataset = datasets.FashionMNIST(root='./data', train=False, transform=transforms_classic, download=True)

train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True, num_workers=4, pin_memory=True, persistent_workers=True)
val_loader = DataLoader(test_dataset, batch_size=128, shuffle=False, num_workers=4, pin_memory=True, persistent_workers=True)
100%|██████████| 26.4M/26.4M [00:01<00:00, 13.7MB/s]
100%|██████████| 29.5k/29.5k [00:00<00:00, 201kB/s]
100%|██████████| 4.42M/4.42M [00:01<00:00, 3.74MB/s]
100%|██████████| 5.15k/5.15k [00:00<00:00, 18.8MB/s]
In [3]:
class LeNetClassic(nn.Module):
  def __init__(self):
    super(LeNetClassic, self).__init__()
    self.features = nn.Sequential(
        nn.Conv2d(1, 6, kernel_size=5, stride=1),
        nn.Tanh(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Conv2d(6, 16, kernel_size=5, stride=1),
        nn.Tanh(),
        nn.AvgPool2d(kernel_size=2, stride=2)
    )

    self.classfier = nn.Sequential(
        nn.Linear(16 * 5 * 5, 120),
        nn.Tanh(),
        nn.Linear(120, 84),
        nn.Tanh(),
        nn.Linear(84, 10)
    )

  def forward(self, x):
    x = self.features(x)
    x = torch.flatten(x, 1)
    x = self.classfier(x)
    return x
In [4]:
model = LeNetClassic().to(device)

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5)

best_acc = 0
epochs = 50

for epoch in range(epochs):
  model.train()
  running_loss = 0.0
  correct = 0
  total = 0

  train_pbar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{epochs} [Train]")
  for inputs, targets in train_pbar:
    inputs, targets = inputs.to(device), targets.to(device)
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss.backward()
    optimizer.step()

    running_loss += loss.item()
    _, predicted = outputs.max(1)
    total += targets.size(0)
    correct += predicted.eq(targets).sum().item()

    train_pbar.set_postfix(loss=running_loss/(total/targets.size(0)), acc=100.*correct/total)

  train_loss = running_loss / len(train_loader)
  train_acc = 100. * correct / total

  model.eval()
  val_loss = 0.0
  val_correct = 0
  val_total = 0

  with torch.no_grad():
    val_pbar = tqdm(val_loader, desc=f"Epoch {epoch+1}/{epochs} [Val]")
    for inputs, targets in val_pbar:
      inputs, targets = inputs.to(device), targets.to(device)
      outputs = model(inputs)
      loss = criterion(outputs, targets)

      val_loss += loss.item()
      _, predicted = outputs.max(1)
      val_total += targets.size(0)
      val_correct += predicted.eq(targets).sum().item()
      val_pbar.set_postfix(loss=val_loss/(val_total/targets.size(0)), acc=100.*val_correct/val_total)

  validation_loss = val_loss / len(val_loader)
  validation_acc = 100. * val_correct / val_total

  print(f"Epoch {epoch+1}/{epochs} | Train Loss: {train_loss:.4f}, Train Acc: {train_acc:.2f}% | Val Loss: {validation_loss:.4f}, Val Acc: {validation_acc:.2f}%")

  scheduler.step()

  if validation_acc > best_acc:
    best_acc = validation_acc
    torch.save(model.state_dict(), 'best_lenet_classic_model.pth')
    print(f"New best model found! Accuracy: {best_acc:.2f}%. Saving model...")

print("\nTraining finished.")
print(f"Best validation accuracy: {best_acc:.2f}%")
Epoch 1/50 [Train]: 100%|██████████| 469/469 [00:05<00:00, 85.56it/s, acc=68, loss=0.671] 
Epoch 1/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 93.31it/s, acc=78.1, loss=0.074] 
Epoch 1/50 | Train Loss: 0.8939, Train Acc: 68.05% | Val Loss: 0.5856, Val Acc: 78.07%
New best model found! Accuracy: 78.07%. Saving model...
Epoch 2/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.00it/s, acc=81.5, loss=0.378]
Epoch 2/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 112.89it/s, acc=82.5, loss=0.0606]
Epoch 2/50 | Train Loss: 0.5036, Train Acc: 81.51% | Val Loss: 0.4797, Val Acc: 82.55%
New best model found! Accuracy: 82.55%. Saving model...
Epoch 3/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.70it/s, acc=84.6, loss=0.319]
Epoch 3/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.32it/s, acc=84.1, loss=0.0547]
Epoch 3/50 | Train Loss: 0.4252, Train Acc: 84.55% | Val Loss: 0.4328, Val Acc: 84.13%
New best model found! Accuracy: 84.13%. Saving model...
Epoch 4/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 111.34it/s, acc=86, loss=0.287]
Epoch 4/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 115.16it/s, acc=86.3, loss=0.0489]
Epoch 4/50 | Train Loss: 0.3824, Train Acc: 86.00% | Val Loss: 0.3872, Val Acc: 86.29%
New best model found! Accuracy: 86.29%. Saving model...
Epoch 5/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 117.14it/s, acc=87.2, loss=0.264]
Epoch 5/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 115.73it/s, acc=87, loss=0.0464]
Epoch 5/50 | Train Loss: 0.3523, Train Acc: 87.22% | Val Loss: 0.3672, Val Acc: 86.96%
New best model found! Accuracy: 86.96%. Saving model...
Epoch 6/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.17it/s, acc=87.9, loss=0.25]
Epoch 6/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 117.51it/s, acc=87.5, loss=0.043]
Epoch 6/50 | Train Loss: 0.3332, Train Acc: 87.88% | Val Loss: 0.3405, Val Acc: 87.49%
New best model found! Accuracy: 87.49%. Saving model...
Epoch 7/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 117.10it/s, acc=88.5, loss=0.237]
Epoch 7/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 114.42it/s, acc=87.7, loss=0.0429]
Epoch 7/50 | Train Loss: 0.3154, Train Acc: 88.47% | Val Loss: 0.3392, Val Acc: 87.70%
New best model found! Accuracy: 87.70%. Saving model...
Epoch 8/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.16it/s, acc=89, loss=0.226]
Epoch 8/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 111.50it/s, acc=88.3, loss=0.0402]
Epoch 8/50 | Train Loss: 0.3015, Train Acc: 89.02% | Val Loss: 0.3182, Val Acc: 88.32%
New best model found! Accuracy: 88.32%. Saving model...
Epoch 9/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.80it/s, acc=89.4, loss=0.217]
Epoch 9/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 114.72it/s, acc=88, loss=0.0419]
Epoch 9/50 | Train Loss: 0.2898, Train Acc: 89.38% | Val Loss: 0.3312, Val Acc: 87.96%
Epoch 10/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.89it/s, acc=89.8, loss=0.21]
Epoch 10/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 109.54it/s, acc=88.1, loss=0.04]
Epoch 10/50 | Train Loss: 0.2794, Train Acc: 89.77% | Val Loss: 0.3167, Val Acc: 88.12%
Epoch 11/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 112.64it/s, acc=90.4, loss=0.196]
Epoch 11/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 111.31it/s, acc=89.4, loss=0.0373]
Epoch 11/50 | Train Loss: 0.2614, Train Acc: 90.42% | Val Loss: 0.2953, Val Acc: 89.38%
New best model found! Accuracy: 89.38%. Saving model...
Epoch 12/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.65it/s, acc=90.7, loss=0.192]
Epoch 12/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 109.24it/s, acc=89, loss=0.0385]
Epoch 12/50 | Train Loss: 0.2557, Train Acc: 90.69% | Val Loss: 0.3043, Val Acc: 88.95%
Epoch 13/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 117.80it/s, acc=90.8, loss=0.189]
Epoch 13/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 112.84it/s, acc=89.7, loss=0.0367]
Epoch 13/50 | Train Loss: 0.2514, Train Acc: 90.79% | Val Loss: 0.2907, Val Acc: 89.68%
New best model found! Accuracy: 89.68%. Saving model...
Epoch 14/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.80it/s, acc=91, loss=0.186]
Epoch 14/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 110.37it/s, acc=89.5, loss=0.0364]
Epoch 14/50 | Train Loss: 0.2480, Train Acc: 90.97% | Val Loss: 0.2880, Val Acc: 89.49%
Epoch 15/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.88it/s, acc=91, loss=0.183]
Epoch 15/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 117.10it/s, acc=89.6, loss=0.0364]
Epoch 15/50 | Train Loss: 0.2443, Train Acc: 91.04% | Val Loss: 0.2878, Val Acc: 89.63%
Epoch 16/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.94it/s, acc=91.2, loss=0.18]
Epoch 16/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 118.24it/s, acc=89.4, loss=0.0361]
Epoch 16/50 | Train Loss: 0.2399, Train Acc: 91.25% | Val Loss: 0.2853, Val Acc: 89.42%
Epoch 17/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 117.68it/s, acc=91.4, loss=0.177]
Epoch 17/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.89it/s, acc=89.5, loss=0.0364]
Epoch 17/50 | Train Loss: 0.2363, Train Acc: 91.38% | Val Loss: 0.2876, Val Acc: 89.46%
Epoch 18/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 112.95it/s, acc=91.5, loss=0.176]
Epoch 18/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 102.96it/s, acc=89.9, loss=0.0354]
Epoch 18/50 | Train Loss: 0.2341, Train Acc: 91.45% | Val Loss: 0.2802, Val Acc: 89.86%
New best model found! Accuracy: 89.86%. Saving model...
Epoch 19/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.05it/s, acc=91.6, loss=0.173]
Epoch 19/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.86it/s, acc=89.6, loss=0.0358]
Epoch 19/50 | Train Loss: 0.2310, Train Acc: 91.56% | Val Loss: 0.2829, Val Acc: 89.64%
Epoch 20/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.25it/s, acc=91.7, loss=0.17]
Epoch 20/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 119.30it/s, acc=89.7, loss=0.0354]
Epoch 20/50 | Train Loss: 0.2263, Train Acc: 91.73% | Val Loss: 0.2803, Val Acc: 89.72%
Epoch 21/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.10it/s, acc=92.1, loss=0.162]
Epoch 21/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.68it/s, acc=90, loss=0.0344]
Epoch 21/50 | Train Loss: 0.2162, Train Acc: 92.14% | Val Loss: 0.2718, Val Acc: 89.95%
New best model found! Accuracy: 89.95%. Saving model...
Epoch 22/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 119.38it/s, acc=92.2, loss=0.161]
Epoch 22/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 117.54it/s, acc=90.1, loss=0.0342]
Epoch 22/50 | Train Loss: 0.2141, Train Acc: 92.19% | Val Loss: 0.2706, Val Acc: 90.07%
New best model found! Accuracy: 90.07%. Saving model...
Epoch 23/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.17it/s, acc=92.3, loss=0.159]
Epoch 23/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 107.02it/s, acc=90.1, loss=0.0346]
Epoch 23/50 | Train Loss: 0.2120, Train Acc: 92.31% | Val Loss: 0.2736, Val Acc: 90.13%
New best model found! Accuracy: 90.13%. Saving model...
Epoch 24/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.15it/s, acc=92.3, loss=0.158]
Epoch 24/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.82it/s, acc=90, loss=0.0346]
Epoch 24/50 | Train Loss: 0.2106, Train Acc: 92.35% | Val Loss: 0.2734, Val Acc: 90.05%
Epoch 25/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.41it/s, acc=92.4, loss=0.157]
Epoch 25/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.12it/s, acc=90.2, loss=0.0342]
Epoch 25/50 | Train Loss: 0.2090, Train Acc: 92.44% | Val Loss: 0.2703, Val Acc: 90.15%
New best model found! Accuracy: 90.15%. Saving model...
Epoch 26/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 115.95it/s, acc=92.5, loss=0.155]
Epoch 26/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 117.26it/s, acc=90, loss=0.0348]
Epoch 26/50 | Train Loss: 0.2069, Train Acc: 92.54% | Val Loss: 0.2752, Val Acc: 90.00%
Epoch 27/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 117.71it/s, acc=92.6, loss=0.154]
Epoch 27/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 115.90it/s, acc=90.1, loss=0.0343]
Epoch 27/50 | Train Loss: 0.2050, Train Acc: 92.58% | Val Loss: 0.2717, Val Acc: 90.14%
Epoch 28/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 115.35it/s, acc=92.7, loss=0.153]
Epoch 28/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.75it/s, acc=90.1, loss=0.0342]
Epoch 28/50 | Train Loss: 0.2038, Train Acc: 92.70% | Val Loss: 0.2703, Val Acc: 90.09%
Epoch 29/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 119.04it/s, acc=92.7, loss=0.152]
Epoch 29/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.24it/s, acc=90.1, loss=0.0347]
Epoch 29/50 | Train Loss: 0.2026, Train Acc: 92.68% | Val Loss: 0.2745, Val Acc: 90.11%
Epoch 30/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.47it/s, acc=92.7, loss=0.151]
Epoch 30/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 107.77it/s, acc=90.1, loss=0.0342]
Epoch 30/50 | Train Loss: 0.2009, Train Acc: 92.70% | Val Loss: 0.2707, Val Acc: 90.10%
Epoch 31/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.39it/s, acc=93, loss=0.147]
Epoch 31/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.19it/s, acc=90.3, loss=0.0336]
Epoch 31/50 | Train Loss: 0.1952, Train Acc: 93.01% | Val Loss: 0.2658, Val Acc: 90.33%
New best model found! Accuracy: 90.33%. Saving model...
Epoch 32/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 115.80it/s, acc=93, loss=0.146]
Epoch 32/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 110.65it/s, acc=90.2, loss=0.0338]
Epoch 32/50 | Train Loss: 0.1939, Train Acc: 92.99% | Val Loss: 0.2676, Val Acc: 90.23%
Epoch 33/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 112.87it/s, acc=93, loss=0.145]
Epoch 33/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 114.48it/s, acc=90.5, loss=0.0334]
Epoch 33/50 | Train Loss: 0.1931, Train Acc: 93.01% | Val Loss: 0.2642, Val Acc: 90.50%
New best model found! Accuracy: 90.50%. Saving model...
Epoch 34/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.21it/s, acc=93.1, loss=0.144]
Epoch 34/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.32it/s, acc=90.3, loss=0.0334]
Epoch 34/50 | Train Loss: 0.1924, Train Acc: 93.13% | Val Loss: 0.2642, Val Acc: 90.33%
Epoch 35/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.11it/s, acc=93.1, loss=0.144]
Epoch 35/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 111.57it/s, acc=90.3, loss=0.0337]
Epoch 35/50 | Train Loss: 0.1915, Train Acc: 93.12% | Val Loss: 0.2666, Val Acc: 90.34%
Epoch 36/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 117.81it/s, acc=93.1, loss=0.143]
Epoch 36/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 118.54it/s, acc=90.3, loss=0.0334]
Epoch 36/50 | Train Loss: 0.1905, Train Acc: 93.11% | Val Loss: 0.2644, Val Acc: 90.27%
Epoch 37/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.17it/s, acc=93.1, loss=0.142]
Epoch 37/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 115.66it/s, acc=90.4, loss=0.0335]
Epoch 37/50 | Train Loss: 0.1898, Train Acc: 93.14% | Val Loss: 0.2649, Val Acc: 90.38%
Epoch 38/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 112.22it/s, acc=93.2, loss=0.142]
Epoch 38/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 112.71it/s, acc=90.3, loss=0.0334]
Epoch 38/50 | Train Loss: 0.1887, Train Acc: 93.21% | Val Loss: 0.2642, Val Acc: 90.32%
Epoch 39/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.08it/s, acc=93.2, loss=0.141]
Epoch 39/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.26it/s, acc=90.4, loss=0.0334]
Epoch 39/50 | Train Loss: 0.1882, Train Acc: 93.19% | Val Loss: 0.2641, Val Acc: 90.37%
Epoch 40/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 115.07it/s, acc=93.2, loss=0.14]
Epoch 40/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 103.70it/s, acc=90.2, loss=0.0338]
Epoch 40/50 | Train Loss: 0.1872, Train Acc: 93.20% | Val Loss: 0.2672, Val Acc: 90.19%
Epoch 41/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.65it/s, acc=93.4, loss=0.138]
Epoch 41/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 114.75it/s, acc=90.4, loss=0.0333]
Epoch 41/50 | Train Loss: 0.1844, Train Acc: 93.40% | Val Loss: 0.2638, Val Acc: 90.40%
Epoch 42/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.60it/s, acc=93.5, loss=0.138]
Epoch 42/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.62it/s, acc=90.4, loss=0.0333]
Epoch 42/50 | Train Loss: 0.1839, Train Acc: 93.45% | Val Loss: 0.2632, Val Acc: 90.37%
Epoch 43/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.00it/s, acc=93.4, loss=0.138]
Epoch 43/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 119.04it/s, acc=90.5, loss=0.0333]
Epoch 43/50 | Train Loss: 0.1833, Train Acc: 93.43% | Val Loss: 0.2632, Val Acc: 90.48%
Epoch 44/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 115.92it/s, acc=93.5, loss=0.137]
Epoch 44/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 116.92it/s, acc=90.4, loss=0.0333]
Epoch 44/50 | Train Loss: 0.1827, Train Acc: 93.51% | Val Loss: 0.2633, Val Acc: 90.37%
Epoch 45/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 113.46it/s, acc=93.4, loss=0.137]
Epoch 45/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 117.78it/s, acc=90.5, loss=0.0331]
Epoch 45/50 | Train Loss: 0.1823, Train Acc: 93.44% | Val Loss: 0.2617, Val Acc: 90.46%
Epoch 46/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.57it/s, acc=93.5, loss=0.136]
Epoch 46/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 113.22it/s, acc=90.4, loss=0.0332]
Epoch 46/50 | Train Loss: 0.1816, Train Acc: 93.52% | Val Loss: 0.2628, Val Acc: 90.43%
Epoch 47/50 [Train]: 100%|██████████| 469/469 [00:03<00:00, 118.81it/s, acc=93.5, loss=0.136]
Epoch 47/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 110.44it/s, acc=90.3, loss=0.0332]
Epoch 47/50 | Train Loss: 0.1813, Train Acc: 93.51% | Val Loss: 0.2623, Val Acc: 90.33%
Epoch 48/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 114.80it/s, acc=93.5, loss=0.136]
Epoch 48/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 115.62it/s, acc=90.5, loss=0.0333]
Epoch 48/50 | Train Loss: 0.1812, Train Acc: 93.55% | Val Loss: 0.2631, Val Acc: 90.45%
Epoch 49/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 116.84it/s, acc=93.4, loss=0.136]
Epoch 49/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 110.64it/s, acc=90.6, loss=0.0332]
Epoch 49/50 | Train Loss: 0.1807, Train Acc: 93.43% | Val Loss: 0.2626, Val Acc: 90.58%
New best model found! Accuracy: 90.58%. Saving model...
Epoch 50/50 [Train]: 100%|██████████| 469/469 [00:04<00:00, 114.09it/s, acc=93.5, loss=0.135]
Epoch 50/50 [Val]: 100%|██████████| 79/79 [00:00<00:00, 112.85it/s, acc=90.4, loss=0.0332]
Epoch 50/50 | Train Loss: 0.1802, Train Acc: 93.50% | Val Loss: 0.2626, Val Acc: 90.44%

Training finished.
Best validation accuracy: 90.58%