Notice
Recent Posts
Recent Comments
Link
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

nevertheless

[논문 리뷰] MobileNetV2 Implementation 본문

AI/논문 리뷰

[논문 리뷰] MobileNetV2 Implementation

우연입니다 2026. 3. 29. 18:39
MobileNetV2 논문을 읽은 뒤 CIFAR-10 분류 실험을 위해 모델을 직접 구현하고 학습해보았다.
논문 정리: https://orchidbyw1.tistory.com/6

모델 설정

  • 코드 베이스: kuangliu/pytorch-cifar 참고
  • 데이터셋: CIFAR-10
  • 모델: MobileNetV2
    • Inverted Residual Block 사용
    • Depthwise Separable Convolution 적용
    • width multiplier=1.2

MobileNetV2는 기존 CNN과 달리, inverted residual 구조를 사용하여 채널을 확장한 뒤 다시 축소하는 방식을 사용한다.

초기 convolution 역시 CIFAR-10 입력 크기(32×32)에 맞게 ImageNet용 구조처럼 stride=2가 아닌, 3×3 conv, stride=1로 설정하였다.

추가로 width multiplier를 사용해 각 state의 채널 수를 일정 비율로 조절할 수 있다.

학습 설정

  • Epoch: 200
  • Batch size: 128
  • Optimizer: SGD
  • Learning rate: 0.1
  • Momentum: 0.9
  • Weight decay: 5e-4

학습은 CIFAR-10 분류에서 일반적으로 사용되는 설정을 따랐으며,

특히 SGD + momentum, 그리고 weight decay를 사용해 안정적으로 학습되도록 했다.

데이터 전처리

  • RandomCrop(32, padding=4)
  • RandomHorizontalFlip
  • Normalize: (0.4914, 0.4822, 0.4465) / (0.2023, 0.1994, 0.2010)

모델 구현
import torch
import torch.nn as nn
import torch.nn.functional as F

def make_divisible(x, divisible_by=8): 
  # 값이 8로 나누어 떨어지게끔 수정
  import numpy as np
  return int(np.ceil(x * 1. / divisible_by) * divisible_by)

class Block(nn.Module): # nn.Module 상속받음

  def __init__(self, in_planes, out_planes, expansion, stride):
    super(Block, self).__init__() # nn.Module 초기화부터

    # stride 저장
    self.stride = stride

    # inverted residual shortcut
    # shortcut은 stride가 1이고, 입력 차원 수와 출력 차원 수가 같은 경우에만
    if stride == 1 and in_planes == out_planes:
      self.use_residual = True
    else:
      self.use_residual = False

    # 확장된 중간 채널 수
    planes = expansion * in_planes

    # 1x1 conv (expand) : Narrow -> Wide
    self.conv1 = nn.Conv2d(
        in_planes, # 입력 채널 수
        planes, # 출력 채널 수 (= 확장 채널 수)
        kernel_size=1, # 1x1 conv
        stride=1,
        padding=0,
        bias=False
    )
    self.bn1 = nn.BatchNorm2d(planes)

    # 3×3 depthwise conv : Wide 유지
    self.conv2 = nn.Conv2d(
        planes, # 입력 채널 수
        planes, # 출력 채널 수 (= 입력 채널 수)
        kernel_size=3, # 3x3 depthwise conv
        stride=stride,
        padding=1,
        groups=planes, # depthwise convolution. 각 채널마다 독립적으로 3x3 conv 수행
        bias=False
    )
    self.bn2 = nn.BatchNorm2d(planes)

    # 1×1 conv (projection) : Wide -> Narrow
    self.conv3 = nn.Conv2d(
        planes, # 입력 채널 수
        out_planes, # 출력 채널 수
        kernel_size=1, # 1x1 conv
        stride=1,
        padding=0,
        bias=False
    )
    self.bn3 = nn.BatchNorm2d(out_planes)

  def forward(self, x): # 블록 출력
    out = self.conv1(x)
    out = self.bn1(out)
    out = F.relu6(out)

    out = self.conv2(out)
    out = self.bn2(out)
    out = F.relu6(out)

    out = self.conv3(out)
    out = self.bn3(out)

    # stride=1이고, 입력/출력 채널이 같을 때만 residual 연결
    if self.use_residual:
      out = out + x

    return out

class MobileNetV2(nn.Module):
  # MobileNetV2 전체 네트워크 구조
  # (expansion, out_planes, num_blocks, stride)
  cfg = [
      (1,  16, 1, 1),
      (6,  24, 2, 1), # NOTE: change stride 2 -> 1 for CIFAR10
      (6,  32, 3, 2),
      (6,  64, 4, 2),
      (6,  96, 3, 1),
      (6, 160, 3, 2),
      (6, 320, 1, 1)
  ]

  def __init__(self, num_classes=10, width_mult=1.):
    super(MobileNetV2, self).__init__()

    self.width_mult = width_mult

    # 마지막 출력 채널
    last_channel = 1280
    self.last_channel = make_divisible(last_channel * width_mult) if width_mult > 1.0 else last_channel # width_multiplier 적용

    # 첫 번째 conv
    self.conv1 = nn.Conv2d(
        3, # RGB 입력
        32, # 첫 출력 채널 수
        kernel_size=3,
        stride=1, # NOTE: change conv1 stride 2 -> 1 for CIFAR10
        padding=1,
        bias=False
    )
    self.bn1 = nn.BatchNorm2d(32)

    # bottleneck block을 순서대로 쌓음
    self.layers = self._make_layers(in_planes=32)
    final_planes = make_divisible(320 * self.width_mult)

    # 마지막 1x1 conv
    self.conv2 = nn.Conv2d(
        final_planes,
        self.last_channel,
        kernel_size=1,
        stride=1,
        padding=0,
        bias=False
    )
    self.bn2 = nn.BatchNorm2d(self.last_channel)

    # 최종 분류기
    self.linear = nn.Linear(self.last_channel, num_classes)

  def _make_layers(self, in_planes):
    # cfg를 읽어서 bottleneck block을 순서대로 생성
    layers = []

    # stage별 설정을 하나씩 읽음
    for expansion, out_planes, num_blocks, stride in self.cfg:
        # 첫 번째 block만 주어진 stride 사용
        # 나머지 block은 stride=1
        # 예: num_blocks=3, stride=2이면 [2,1,1] 형태로 block 생성
        strides = [stride] + [1] * (num_blocks - 1)

        # 모든 out_planes에 width_multiplier 적용
        output_planes = make_divisible(out_planes * self.width_mult)

        for stride in strides:
            # block 하나 추가
            layers.append(Block(in_planes, output_planes, expansion, stride))

            # 다음 block의 입력 채널은 현재 출력 채널이 됨
            in_planes = output_planes

    # 만든 block 리스트 보냄
    return nn.Sequential(*layers)

  def forward(self, x):
    # 첫 conv + BN + ReLU
    out = F.relu6(self.bn1(self.conv1(x)))

    # bottleneck block들 통과
    out = self.layers(out)

    # 마지막 1x1 conv + BN + ReLU
    out = F.relu6(self.bn2(self.conv2(out)))

    out = F.avg_pool2d(out, 4) # # NOTE: change pooling kernel_size 7 -> 4 for CIFAR10
    out = out.view(out.size(0), -1) # flatten
    out = self.linear(out) # fully connected

    return out

 

학습 및 테스트
import copy
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import torch.backends.cudnn as cudnn
from torch.utils.data import DataLoader, random_split
import matplotlib.pyplot as plt

# =========================================================
# 0. 기본 세팅
# =========================================================

# GPU 사용 가능하면 GPU 사용
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print("Device:", device)

# epoch 수
num_epochs = 200

# batch size
train_batch_size = 128
eval_batch_size = 100

# 재현성을 위해 seed 고정
seed = 42
torch.manual_seed(seed)
if torch.cuda.is_available():
    torch.cuda.manual_seed_all(seed)

# =========================================================
# 1. 데이터 전처리
# =========================================================

# train용 transform
# 데이터 증강 포함
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),          # 32x32 이미지 주변 padding 후 랜덤 crop
    transforms.RandomHorizontalFlip(),             # 좌우 반전
    transforms.ToTensor(),                         # Tensor 변환
    transforms.Normalize((0.4914, 0.4822, 0.4465), # CIFAR-10 mean
                         (0.2023, 0.1994, 0.2010)) # CIFAR-10 std
])

# val / test용 transform
# 성능 평가용이므로 augmentation 없이 정규화만 수행
transform_eval = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465),
                         (0.2023, 0.1994, 0.2010))
])

# =========================================================
# 2. 데이터셋 준비
# =========================================================

# CIFAR-10 train 전체(50000장)를 먼저 불러옴
# 여기서 train / validation으로 다시 분리할 것
full_trainset = torchvision.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform_train   # 우선 train transform으로 불러옴
)

# validation용 데이터는 augmentation이 없어야 하므로
# 같은 train=True 데이터를 transform_eval로 하나 더 불러옴
full_valset = torchvision.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform_eval
)

# train/val 분할 비율 설정
# 예: 45000 / 5000
train_size = 45000
val_size = 50000 - train_size

# 같은 인덱스로 나누기 위해 generator에 seed 고정
generator = torch.Generator().manual_seed(seed)

# 인덱스 기준으로 train / val 분할
train_subset_indices, val_subset_indices = random_split(
    range(50000),
    [train_size, val_size],
    generator=generator
)

# random_split이 Subset 객체를 반환하므로 indices 추출
train_indices = train_subset_indices.indices
val_indices = val_subset_indices.indices

# trainset / valset 생성
trainset = torch.utils.data.Subset(full_trainset, train_indices)
valset = torch.utils.data.Subset(full_valset, val_indices)

# test set은 마지막 최종 평가용
testset = torchvision.datasets.CIFAR10(
    root='./data',
    train=False,
    download=True,
    transform=transform_eval
)

# =========================================================
# 3. DataLoader 준비
# =========================================================

trainloader = DataLoader(
    trainset,
    batch_size=train_batch_size,
    shuffle=True,         # train은 섞음
    num_workers=2
)

valloader = DataLoader(
    valset,
    batch_size=eval_batch_size,
    shuffle=False,        # val은 섞을 필요 없음
    num_workers=2
)

testloader = DataLoader(
    testset,
    batch_size=eval_batch_size,
    shuffle=False,        # test도 섞을 필요 없음
    num_workers=2
)

# =========================================================
# 4. 모델 준비
# =========================================================

net = MobileNetV2(width_mult=1.2)
net = net.to(device)

if device == 'cuda':
    net = torch.nn.DataParallel(net)  # 여러 GPU 사용 가능 시 병렬 처리
    cudnn.benchmark = True

# =========================================================
# 5. loss / optimizer / scheduler
# =========================================================

criterion = nn.CrossEntropyLoss()

optimizer = optim.SGD(
    net.parameters(),
    lr=0.1,
    momentum=0.9,
    weight_decay=5e-4
)

scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
    optimizer,
    T_max=num_epochs
)

# =========================================================
# 6. 학습 함수
# =========================================================

def train_one_epoch(model, loader, criterion, optimizer, device):
    """
    한 epoch 동안 학습 수행
    반환값:
      - avg_loss: epoch 평균 train loss
      - acc: epoch train accuracy
    """
    model.train()  # 학습 모드
    running_loss = 0.0
    correct = 0
    total = 0

    for inputs, targets in loader:
        # 데이터를 device로 이동
        inputs, targets = inputs.to(device), targets.to(device)

        # gradient 초기화
        optimizer.zero_grad()

        # forward
        outputs = model(inputs)

        # loss 계산
        loss = criterion(outputs, targets)

        # backward
        loss.backward()

        # weight update
        optimizer.step()

        # loss 누적
        running_loss += loss.item()

        # accuracy 계산
        _, predicted = outputs.max(1)
        total += targets.size(0)
        correct += predicted.eq(targets).sum().item()

    avg_loss = running_loss / len(loader)
    acc = 100.0 * correct / total

    return avg_loss, acc

# =========================================================
# 7. 평가 함수 (validation / test 공용)
# =========================================================

def evaluate(model, loader, criterion, device):
    """
    validation / test 공용 평가 함수
    반환값:
      - avg_loss: 평균 loss
      - acc: accuracy
    """
    model.eval()  # 평가 모드
    running_loss = 0.0
    correct = 0
    total = 0

    with torch.no_grad():  # gradient 계산 비활성화
        for inputs, targets in loader:
            inputs, targets = inputs.to(device), targets.to(device)

            outputs = model(inputs)
            loss = criterion(outputs, targets)

            running_loss += loss.item()

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

    avg_loss = running_loss / len(loader)
    acc = 100.0 * correct / total

    return avg_loss, acc

# =========================================================
# 8. 기록용 리스트
# =========================================================

train_losses = []
train_accs = []
val_losses = []
val_accs = []

# validation 기준 최고 성능 기록
best_val_acc = 0.0
best_epoch = 0

# 가장 성능이 좋았던 모델 가중치 저장용
best_model_wts = copy.deepcopy(net.state_dict())

# =========================================================
# 9. 메인 학습 루프
# =========================================================

print("----- Start Training -----")

for epoch in range(num_epochs):
    # 1) train
    train_loss, train_acc = train_one_epoch(
        model=net,
        loader=trainloader,
        criterion=criterion,
        optimizer=optimizer,
        device=device
    )

    # 2) validation
    # test set이 아니라 validation set으로만 중간 성능 확인
    val_loss, val_acc = evaluate(
        model=net,
        loader=valloader,
        criterion=criterion,
        device=device
    )

    # 3) scheduler step
    scheduler.step()
    current_lr = optimizer.param_groups[0]['lr']

    # 4) 기록 저장
    train_losses.append(train_loss)
    train_accs.append(train_acc)
    val_losses.append(val_loss)
    val_accs.append(val_acc)

    # 5) best validation checkpoint 저장
    # test accuracy가 아니라 val accuracy 기준으로 저장하는 것이 핵심
    if val_acc > best_val_acc:
        best_val_acc = val_acc
        best_epoch = epoch + 1
        best_model_wts = copy.deepcopy(net.state_dict())

    # 6) 로그 출력
    print(
        f"Epoch [{epoch+1}/{num_epochs}] | "
        f"LR: {current_lr:.5f} | "
        f"Train Loss: {train_loss:.4f} | "
        f"Train Acc: {train_acc:.2f}% | "
        f"Val Loss: {val_loss:.4f} | "
        f"Val Acc: {val_acc:.2f}% | "
        f"Best Val Acc: {best_val_acc:.2f}%"
    )

print("----- Finished Training -----")
print(f"Best Validation Accuracy: {best_val_acc:.2f}% (Epoch {best_epoch})")

# =========================================================
# 10. 최종 테스트
# =========================================================
# 학습이 끝난 뒤, validation 성능이 가장 좋았던 checkpoint를 불러와서
# test set으로 단 한 번 최종 평가

net.load_state_dict(best_model_wts)

test_loss, test_acc = evaluate(
    model=net,
    loader=testloader,
    criterion=criterion,
    device=device
)

print("----- Final Test Result -----")
print(f"Test Loss: {test_loss:.4f}")
print(f"Final Test Accuracy: {test_acc:.2f}%")

# =========================================================
# 11. learning curve 시각화
# =========================================================

epochs = list(range(1, num_epochs + 1))

plt.figure(figsize=(12, 5))

# (1) Loss curve
plt.subplot(1, 2, 1)
plt.plot(epochs, train_losses, label='Train Loss')
plt.plot(epochs, val_losses, label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Learning Curve - Loss')
plt.legend()
plt.grid(True)

# (2) Accuracy curve
plt.subplot(1, 2, 2)
plt.plot(epochs, train_accs, label='Train Accuracy')
plt.plot(epochs, val_accs, label='Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy (%)')
plt.title('Learning Curve - Accuracy')
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()

 

결과

이번 실험에서는 width_mult = 1.2를 적용한 MobileNetV2를 사용했고,

기본 구조보다 채널 수를 확장한 결과 최종 정확도 92.54%를 얻었다.

Device: cuda
100%|██████████| 170M/170M [00:03<00:00, 47.8MB/s]
----- Start Training -----
Epoch [1/200] | LR: 0.09999 | Train Loss: 1.9974 | Train Acc: 29.80% | Val Loss: 1.5663 | Val Acc: 41.14% | Best Val Acc: 41.14%
Epoch [2/200] | LR: 0.09998 | Train Loss: 1.4274 | Train Acc: 47.27% | Val Loss: 1.2860 | Val Acc: 53.78% | Best Val Acc: 53.78%
Epoch [3/200] | LR: 0.09994 | Train Loss: 1.1164 | Train Acc: 60.11% | Val Loss: 0.9407 | Val Acc: 65.66% | Best Val Acc: 65.66%
Epoch [4/200] | LR: 0.09990 | Train Loss: 0.9141 | Train Acc: 67.91% | Val Loss: 0.9934 | Val Acc: 65.82% | Best Val Acc: 65.82%
Epoch [5/200] | LR: 0.09985 | Train Loss: 0.8009 | Train Acc: 72.36% | Val Loss: 0.7539 | Val Acc: 73.22% | Best Val Acc: 73.22%
Epoch [6/200] | LR: 0.09978 | Train Loss: 0.7285 | Train Acc: 74.66% | Val Loss: 0.8272 | Val Acc: 71.10% | Best Val Acc: 73.22%
Epoch [7/200] | LR: 0.09970 | Train Loss: 0.6842 | Train Acc: 76.49% | Val Loss: 0.7776 | Val Acc: 73.58% | Best Val Acc: 73.58%
Epoch [8/200] | LR: 0.09961 | Train Loss: 0.6569 | Train Acc: 77.35% | Val Loss: 0.8244 | Val Acc: 71.90% | Best Val Acc: 73.58%
Epoch [9/200] | LR: 0.09950 | Train Loss: 0.6385 | Train Acc: 77.94% | Val Loss: 0.6996 | Val Acc: 75.14% | Best Val Acc: 75.14%
Epoch [10/200] | LR: 0.09938 | Train Loss: 0.6254 | Train Acc: 78.42% | Val Loss: 0.7603 | Val Acc: 73.76% | Best Val Acc: 75.14%
Epoch [11/200] | LR: 0.09926 | Train Loss: 0.6192 | Train Acc: 78.74% | Val Loss: 0.8271 | Val Acc: 72.22% | Best Val Acc: 75.14%
Epoch [12/200] | LR: 0.09911 | Train Loss: 0.6151 | Train Acc: 79.01% | Val Loss: 0.7280 | Val Acc: 75.00% | Best Val Acc: 75.14%
Epoch [13/200] | LR: 0.09896 | Train Loss: 0.6170 | Train Acc: 78.72% | Val Loss: 0.6561 | Val Acc: 77.68% | Best Val Acc: 77.68%
Epoch [14/200] | LR: 0.09880 | Train Loss: 0.6018 | Train Acc: 79.33% | Val Loss: 0.7709 | Val Acc: 73.28% | Best Val Acc: 77.68%
Epoch [15/200] | LR: 0.09862 | Train Loss: 0.6073 | Train Acc: 79.05% | Val Loss: 0.7211 | Val Acc: 75.24% | Best Val Acc: 77.68%
Epoch [16/200] | LR: 0.09843 | Train Loss: 0.6032 | Train Acc: 79.36% | Val Loss: 0.7369 | Val Acc: 75.12% | Best Val Acc: 77.68%
Epoch [17/200] | LR: 0.09823 | Train Loss: 0.5980 | Train Acc: 79.53% | Val Loss: 0.7522 | Val Acc: 74.58% | Best Val Acc: 77.68%
Epoch [18/200] | LR: 0.09801 | Train Loss: 0.5907 | Train Acc: 79.78% | Val Loss: 0.6920 | Val Acc: 76.48% | Best Val Acc: 77.68%
Epoch [19/200] | LR: 0.09779 | Train Loss: 0.5922 | Train Acc: 79.68% | Val Loss: 0.7016 | Val Acc: 76.00% | Best Val Acc: 77.68%
Epoch [20/200] | LR: 0.09755 | Train Loss: 0.5892 | Train Acc: 79.90% | Val Loss: 0.7349 | Val Acc: 74.92% | Best Val Acc: 77.68%
Epoch [21/200] | LR: 0.09730 | Train Loss: 0.5925 | Train Acc: 79.74% | Val Loss: 0.7101 | Val Acc: 75.80% | Best Val Acc: 77.68%
Epoch [22/200] | LR: 0.09704 | Train Loss: 0.5832 | Train Acc: 79.93% | Val Loss: 0.7502 | Val Acc: 74.02% | Best Val Acc: 77.68%
Epoch [23/200] | LR: 0.09677 | Train Loss: 0.5839 | Train Acc: 79.91% | Val Loss: 0.8503 | Val Acc: 71.16% | Best Val Acc: 77.68%
Epoch [24/200] | LR: 0.09649 | Train Loss: 0.5783 | Train Acc: 80.24% | Val Loss: 0.6604 | Val Acc: 77.20% | Best Val Acc: 77.68%
Epoch [25/200] | LR: 0.09619 | Train Loss: 0.5815 | Train Acc: 80.02% | Val Loss: 0.6388 | Val Acc: 78.30% | Best Val Acc: 78.30%
Epoch [26/200] | LR: 0.09589 | Train Loss: 0.5787 | Train Acc: 80.20% | Val Loss: 0.5948 | Val Acc: 79.08% | Best Val Acc: 79.08%
Epoch [27/200] | LR: 0.09557 | Train Loss: 0.5773 | Train Acc: 80.39% | Val Loss: 0.5843 | Val Acc: 80.16% | Best Val Acc: 80.16%
Epoch [28/200] | LR: 0.09524 | Train Loss: 0.5728 | Train Acc: 80.32% | Val Loss: 0.6285 | Val Acc: 78.54% | Best Val Acc: 80.16%
Epoch [29/200] | LR: 0.09490 | Train Loss: 0.5700 | Train Acc: 80.39% | Val Loss: 0.7197 | Val Acc: 75.54% | Best Val Acc: 80.16%
Epoch [30/200] | LR: 0.09455 | Train Loss: 0.5676 | Train Acc: 80.67% | Val Loss: 0.7803 | Val Acc: 74.18% | Best Val Acc: 80.16%
Epoch [31/200] | LR: 0.09419 | Train Loss: 0.5667 | Train Acc: 80.69% | Val Loss: 0.7748 | Val Acc: 74.58% | Best Val Acc: 80.16%
Epoch [32/200] | LR: 0.09382 | Train Loss: 0.5692 | Train Acc: 80.42% | Val Loss: 0.7064 | Val Acc: 76.10% | Best Val Acc: 80.16%
Epoch [33/200] | LR: 0.09343 | Train Loss: 0.5622 | Train Acc: 80.76% | Val Loss: 0.7111 | Val Acc: 75.66% | Best Val Acc: 80.16%
Epoch [34/200] | LR: 0.09304 | Train Loss: 0.5692 | Train Acc: 80.63% | Val Loss: 0.7814 | Val Acc: 73.72% | Best Val Acc: 80.16%
Epoch [35/200] | LR: 0.09263 | Train Loss: 0.5503 | Train Acc: 81.10% | Val Loss: 0.7076 | Val Acc: 76.20% | Best Val Acc: 80.16%
Epoch [36/200] | LR: 0.09222 | Train Loss: 0.5595 | Train Acc: 80.74% | Val Loss: 0.6215 | Val Acc: 78.90% | Best Val Acc: 80.16%
Epoch [37/200] | LR: 0.09179 | Train Loss: 0.5565 | Train Acc: 80.96% | Val Loss: 0.6221 | Val Acc: 78.02% | Best Val Acc: 80.16%
Epoch [38/200] | LR: 0.09135 | Train Loss: 0.5590 | Train Acc: 80.84% | Val Loss: 0.5923 | Val Acc: 79.70% | Best Val Acc: 80.16%
Epoch [39/200] | LR: 0.09091 | Train Loss: 0.5487 | Train Acc: 81.35% | Val Loss: 0.5373 | Val Acc: 81.90% | Best Val Acc: 81.90%
Epoch [40/200] | LR: 0.09045 | Train Loss: 0.5526 | Train Acc: 81.00% | Val Loss: 0.5864 | Val Acc: 79.98% | Best Val Acc: 81.90%
Epoch [41/200] | LR: 0.08998 | Train Loss: 0.5502 | Train Acc: 81.22% | Val Loss: 0.8912 | Val Acc: 70.06% | Best Val Acc: 81.90%
Epoch [42/200] | LR: 0.08951 | Train Loss: 0.5508 | Train Acc: 81.10% | Val Loss: 0.6399 | Val Acc: 77.68% | Best Val Acc: 81.90%
Epoch [43/200] | LR: 0.08902 | Train Loss: 0.5502 | Train Acc: 80.96% | Val Loss: 0.7389 | Val Acc: 75.38% | Best Val Acc: 81.90%
Epoch [44/200] | LR: 0.08853 | Train Loss: 0.5603 | Train Acc: 80.83% | Val Loss: 0.5625 | Val Acc: 81.10% | Best Val Acc: 81.90%
Epoch [45/200] | LR: 0.08802 | Train Loss: 0.5562 | Train Acc: 81.11% | Val Loss: 0.6520 | Val Acc: 77.16% | Best Val Acc: 81.90%
Epoch [46/200] | LR: 0.08751 | Train Loss: 0.5475 | Train Acc: 81.10% | Val Loss: 0.6097 | Val Acc: 79.38% | Best Val Acc: 81.90%
Epoch [47/200] | LR: 0.08698 | Train Loss: 0.5550 | Train Acc: 80.95% | Val Loss: 0.6859 | Val Acc: 76.90% | Best Val Acc: 81.90%
Epoch [48/200] | LR: 0.08645 | Train Loss: 0.5434 | Train Acc: 81.37% | Val Loss: 0.6728 | Val Acc: 76.70% | Best Val Acc: 81.90%
Epoch [49/200] | LR: 0.08591 | Train Loss: 0.5401 | Train Acc: 81.53% | Val Loss: 0.6797 | Val Acc: 76.80% | Best Val Acc: 81.90%
Epoch [50/200] | LR: 0.08536 | Train Loss: 0.5437 | Train Acc: 81.39% | Val Loss: 0.6825 | Val Acc: 76.64% | Best Val Acc: 81.90%
Epoch [51/200] | LR: 0.08480 | Train Loss: 0.5409 | Train Acc: 81.55% | Val Loss: 0.5767 | Val Acc: 80.08% | Best Val Acc: 81.90%
Epoch [52/200] | LR: 0.08423 | Train Loss: 0.5416 | Train Acc: 81.52% | Val Loss: 0.8100 | Val Acc: 74.18% | Best Val Acc: 81.90%
Epoch [53/200] | LR: 0.08365 | Train Loss: 0.5299 | Train Acc: 81.92% | Val Loss: 0.5964 | Val Acc: 79.54% | Best Val Acc: 81.90%
Epoch [54/200] | LR: 0.08307 | Train Loss: 0.5311 | Train Acc: 81.84% | Val Loss: 0.7858 | Val Acc: 74.28% | Best Val Acc: 81.90%
Epoch [55/200] | LR: 0.08247 | Train Loss: 0.5362 | Train Acc: 81.79% | Val Loss: 0.7073 | Val Acc: 77.24% | Best Val Acc: 81.90%
Epoch [56/200] | LR: 0.08187 | Train Loss: 0.5271 | Train Acc: 81.98% | Val Loss: 0.6472 | Val Acc: 77.94% | Best Val Acc: 81.90%
Epoch [57/200] | LR: 0.08126 | Train Loss: 0.5328 | Train Acc: 81.64% | Val Loss: 0.6827 | Val Acc: 76.46% | Best Val Acc: 81.90%
Epoch [58/200] | LR: 0.08065 | Train Loss: 0.5331 | Train Acc: 81.78% | Val Loss: 0.6209 | Val Acc: 78.76% | Best Val Acc: 81.90%
Epoch [59/200] | LR: 0.08002 | Train Loss: 0.5238 | Train Acc: 82.07% | Val Loss: 0.7764 | Val Acc: 74.98% | Best Val Acc: 81.90%
Epoch [60/200] | LR: 0.07939 | Train Loss: 0.5221 | Train Acc: 82.22% | Val Loss: 0.6243 | Val Acc: 78.54% | Best Val Acc: 81.90%
Epoch [61/200] | LR: 0.07875 | Train Loss: 0.5324 | Train Acc: 81.87% | Val Loss: 0.6780 | Val Acc: 76.74% | Best Val Acc: 81.90%
Epoch [62/200] | LR: 0.07810 | Train Loss: 0.5245 | Train Acc: 82.16% | Val Loss: 0.5862 | Val Acc: 79.80% | Best Val Acc: 81.90%
Epoch [63/200] | LR: 0.07745 | Train Loss: 0.5144 | Train Acc: 82.49% | Val Loss: 0.6430 | Val Acc: 77.88% | Best Val Acc: 81.90%
Epoch [64/200] | LR: 0.07679 | Train Loss: 0.5181 | Train Acc: 82.20% | Val Loss: 0.6136 | Val Acc: 79.74% | Best Val Acc: 81.90%
Epoch [65/200] | LR: 0.07612 | Train Loss: 0.5142 | Train Acc: 82.42% | Val Loss: 0.6201 | Val Acc: 77.88% | Best Val Acc: 81.90%
Epoch [66/200] | LR: 0.07545 | Train Loss: 0.5217 | Train Acc: 82.01% | Val Loss: 0.7117 | Val Acc: 76.56% | Best Val Acc: 81.90%
Epoch [67/200] | LR: 0.07477 | Train Loss: 0.5171 | Train Acc: 82.40% | Val Loss: 0.6412 | Val Acc: 78.78% | Best Val Acc: 81.90%
Epoch [68/200] | LR: 0.07409 | Train Loss: 0.5187 | Train Acc: 82.25% | Val Loss: 0.5957 | Val Acc: 78.68% | Best Val Acc: 81.90%
Epoch [69/200] | LR: 0.07340 | Train Loss: 0.5160 | Train Acc: 82.12% | Val Loss: 0.6773 | Val Acc: 77.54% | Best Val Acc: 81.90%
Epoch [70/200] | LR: 0.07270 | Train Loss: 0.5161 | Train Acc: 82.41% | Val Loss: 0.6510 | Val Acc: 77.86% | Best Val Acc: 81.90%
Epoch [71/200] | LR: 0.07200 | Train Loss: 0.5155 | Train Acc: 82.43% | Val Loss: 0.5368 | Val Acc: 81.68% | Best Val Acc: 81.90%
Epoch [72/200] | LR: 0.07129 | Train Loss: 0.5074 | Train Acc: 82.60% | Val Loss: 0.5805 | Val Acc: 80.88% | Best Val Acc: 81.90%
Epoch [73/200] | LR: 0.07058 | Train Loss: 0.5080 | Train Acc: 82.54% | Val Loss: 0.5013 | Val Acc: 82.32% | Best Val Acc: 82.32%
Epoch [74/200] | LR: 0.06986 | Train Loss: 0.5080 | Train Acc: 82.55% | Val Loss: 0.6255 | Val Acc: 78.92% | Best Val Acc: 82.32%
Epoch [75/200] | LR: 0.06913 | Train Loss: 0.5064 | Train Acc: 82.73% | Val Loss: 0.7056 | Val Acc: 77.22% | Best Val Acc: 82.32%
Epoch [76/200] | LR: 0.06841 | Train Loss: 0.4943 | Train Acc: 82.96% | Val Loss: 0.5980 | Val Acc: 79.62% | Best Val Acc: 82.32%
Epoch [77/200] | LR: 0.06767 | Train Loss: 0.5037 | Train Acc: 82.64% | Val Loss: 0.6302 | Val Acc: 78.72% | Best Val Acc: 82.32%
Epoch [78/200] | LR: 0.06694 | Train Loss: 0.4903 | Train Acc: 83.23% | Val Loss: 0.5753 | Val Acc: 80.74% | Best Val Acc: 82.32%
Epoch [79/200] | LR: 0.06620 | Train Loss: 0.4967 | Train Acc: 82.87% | Val Loss: 0.6115 | Val Acc: 79.50% | Best Val Acc: 82.32%
Epoch [80/200] | LR: 0.06545 | Train Loss: 0.4880 | Train Acc: 83.20% | Val Loss: 0.6259 | Val Acc: 79.24% | Best Val Acc: 82.32%
Epoch [81/200] | LR: 0.06470 | Train Loss: 0.4842 | Train Acc: 83.34% | Val Loss: 0.7023 | Val Acc: 77.56% | Best Val Acc: 82.32%
Epoch [82/200] | LR: 0.06395 | Train Loss: 0.4876 | Train Acc: 83.29% | Val Loss: 0.5081 | Val Acc: 81.98% | Best Val Acc: 82.32%
Epoch [83/200] | LR: 0.06319 | Train Loss: 0.4881 | Train Acc: 83.25% | Val Loss: 0.5338 | Val Acc: 81.76% | Best Val Acc: 82.32%
Epoch [84/200] | LR: 0.06243 | Train Loss: 0.4882 | Train Acc: 83.16% | Val Loss: 0.6907 | Val Acc: 76.76% | Best Val Acc: 82.32%
Epoch [85/200] | LR: 0.06167 | Train Loss: 0.4783 | Train Acc: 83.75% | Val Loss: 0.5718 | Val Acc: 80.42% | Best Val Acc: 82.32%
Epoch [86/200] | LR: 0.06091 | Train Loss: 0.4739 | Train Acc: 83.70% | Val Loss: 0.6410 | Val Acc: 78.52% | Best Val Acc: 82.32%
Epoch [87/200] | LR: 0.06014 | Train Loss: 0.4839 | Train Acc: 83.44% | Val Loss: 0.5362 | Val Acc: 82.06% | Best Val Acc: 82.32%
Epoch [88/200] | LR: 0.05937 | Train Loss: 0.4777 | Train Acc: 83.68% | Val Loss: 0.5780 | Val Acc: 80.76% | Best Val Acc: 82.32%
Epoch [89/200] | LR: 0.05860 | Train Loss: 0.4784 | Train Acc: 83.66% | Val Loss: 0.6281 | Val Acc: 78.54% | Best Val Acc: 82.32%
Epoch [90/200] | LR: 0.05782 | Train Loss: 0.4676 | Train Acc: 84.05% | Val Loss: 0.5272 | Val Acc: 82.52% | Best Val Acc: 82.52%
Epoch [91/200] | LR: 0.05705 | Train Loss: 0.4712 | Train Acc: 83.89% | Val Loss: 0.6491 | Val Acc: 78.76% | Best Val Acc: 82.52%
Epoch [92/200] | LR: 0.05627 | Train Loss: 0.4740 | Train Acc: 83.86% | Val Loss: 0.6244 | Val Acc: 78.60% | Best Val Acc: 82.52%
Epoch [93/200] | LR: 0.05549 | Train Loss: 0.4726 | Train Acc: 83.88% | Val Loss: 0.5745 | Val Acc: 80.36% | Best Val Acc: 82.52%
Epoch [94/200] | LR: 0.05471 | Train Loss: 0.4586 | Train Acc: 84.36% | Val Loss: 0.5521 | Val Acc: 81.56% | Best Val Acc: 82.52%
Epoch [95/200] | LR: 0.05392 | Train Loss: 0.4592 | Train Acc: 84.29% | Val Loss: 0.5052 | Val Acc: 83.00% | Best Val Acc: 83.00%
Epoch [96/200] | LR: 0.05314 | Train Loss: 0.4522 | Train Acc: 84.57% | Val Loss: 0.5735 | Val Acc: 80.24% | Best Val Acc: 83.00%
Epoch [97/200] | LR: 0.05236 | Train Loss: 0.4565 | Train Acc: 84.25% | Val Loss: 0.6130 | Val Acc: 79.38% | Best Val Acc: 83.00%
Epoch [98/200] | LR: 0.05157 | Train Loss: 0.4482 | Train Acc: 84.61% | Val Loss: 0.5756 | Val Acc: 79.70% | Best Val Acc: 83.00%
Epoch [99/200] | LR: 0.05079 | Train Loss: 0.4482 | Train Acc: 84.63% | Val Loss: 0.4899 | Val Acc: 83.96% | Best Val Acc: 83.96%
Epoch [100/200] | LR: 0.05000 | Train Loss: 0.4484 | Train Acc: 84.75% | Val Loss: 0.5336 | Val Acc: 81.34% | Best Val Acc: 83.96%
Epoch [101/200] | LR: 0.04921 | Train Loss: 0.4405 | Train Acc: 84.74% | Val Loss: 0.5255 | Val Acc: 81.90% | Best Val Acc: 83.96%
Epoch [102/200] | LR: 0.04843 | Train Loss: 0.4421 | Train Acc: 84.81% | Val Loss: 0.5804 | Val Acc: 80.14% | Best Val Acc: 83.96%
Epoch [103/200] | LR: 0.04764 | Train Loss: 0.4408 | Train Acc: 84.87% | Val Loss: 0.4959 | Val Acc: 83.26% | Best Val Acc: 83.96%
Epoch [104/200] | LR: 0.04686 | Train Loss: 0.4269 | Train Acc: 85.27% | Val Loss: 0.4735 | Val Acc: 83.58% | Best Val Acc: 83.96%
Epoch [105/200] | LR: 0.04608 | Train Loss: 0.4289 | Train Acc: 85.17% | Val Loss: 0.4717 | Val Acc: 83.42% | Best Val Acc: 83.96%
Epoch [106/200] | LR: 0.04529 | Train Loss: 0.4195 | Train Acc: 85.66% | Val Loss: 0.5984 | Val Acc: 79.56% | Best Val Acc: 83.96%
Epoch [107/200] | LR: 0.04451 | Train Loss: 0.4197 | Train Acc: 85.60% | Val Loss: 0.5283 | Val Acc: 82.26% | Best Val Acc: 83.96%
Epoch [108/200] | LR: 0.04373 | Train Loss: 0.4195 | Train Acc: 85.55% | Val Loss: 0.4535 | Val Acc: 84.08% | Best Val Acc: 84.08%
Epoch [109/200] | LR: 0.04295 | Train Loss: 0.4194 | Train Acc: 85.71% | Val Loss: 0.4737 | Val Acc: 83.42% | Best Val Acc: 84.08%
Epoch [110/200] | LR: 0.04218 | Train Loss: 0.4147 | Train Acc: 85.74% | Val Loss: 0.4653 | Val Acc: 83.74% | Best Val Acc: 84.08%
Epoch [111/200] | LR: 0.04140 | Train Loss: 0.4077 | Train Acc: 86.22% | Val Loss: 0.4477 | Val Acc: 84.38% | Best Val Acc: 84.38%
Epoch [112/200] | LR: 0.04063 | Train Loss: 0.4013 | Train Acc: 86.29% | Val Loss: 0.4692 | Val Acc: 83.64% | Best Val Acc: 84.38%
Epoch [113/200] | LR: 0.03986 | Train Loss: 0.4054 | Train Acc: 86.00% | Val Loss: 0.4585 | Val Acc: 84.34% | Best Val Acc: 84.38%
Epoch [114/200] | LR: 0.03909 | Train Loss: 0.3946 | Train Acc: 86.49% | Val Loss: 0.4615 | Val Acc: 83.80% | Best Val Acc: 84.38%
Epoch [115/200] | LR: 0.03833 | Train Loss: 0.3860 | Train Acc: 86.73% | Val Loss: 0.5002 | Val Acc: 82.44% | Best Val Acc: 84.38%
Epoch [116/200] | LR: 0.03757 | Train Loss: 0.3925 | Train Acc: 86.50% | Val Loss: 0.4565 | Val Acc: 84.58% | Best Val Acc: 84.58%
Epoch [117/200] | LR: 0.03681 | Train Loss: 0.3918 | Train Acc: 86.44% | Val Loss: 0.4090 | Val Acc: 86.40% | Best Val Acc: 86.40%
Epoch [118/200] | LR: 0.03605 | Train Loss: 0.3791 | Train Acc: 87.08% | Val Loss: 0.4420 | Val Acc: 85.16% | Best Val Acc: 86.40%
Epoch [119/200] | LR: 0.03530 | Train Loss: 0.3808 | Train Acc: 86.90% | Val Loss: 0.4362 | Val Acc: 85.00% | Best Val Acc: 86.40%
Epoch [120/200] | LR: 0.03455 | Train Loss: 0.3753 | Train Acc: 87.22% | Val Loss: 0.4292 | Val Acc: 85.34% | Best Val Acc: 86.40%
Epoch [121/200] | LR: 0.03380 | Train Loss: 0.3682 | Train Acc: 87.21% | Val Loss: 0.4406 | Val Acc: 85.06% | Best Val Acc: 86.40%
Epoch [122/200] | LR: 0.03306 | Train Loss: 0.3638 | Train Acc: 87.54% | Val Loss: 0.3913 | Val Acc: 86.58% | Best Val Acc: 86.58%
Epoch [123/200] | LR: 0.03233 | Train Loss: 0.3586 | Train Acc: 87.77% | Val Loss: 0.4675 | Val Acc: 84.30% | Best Val Acc: 86.58%
Epoch [124/200] | LR: 0.03159 | Train Loss: 0.3581 | Train Acc: 87.70% | Val Loss: 0.4790 | Val Acc: 84.24% | Best Val Acc: 86.58%
Epoch [125/200] | LR: 0.03087 | Train Loss: 0.3576 | Train Acc: 87.71% | Val Loss: 0.3939 | Val Acc: 86.34% | Best Val Acc: 86.58%
Epoch [126/200] | LR: 0.03014 | Train Loss: 0.3552 | Train Acc: 87.61% | Val Loss: 0.3921 | Val Acc: 86.64% | Best Val Acc: 86.64%
Epoch [127/200] | LR: 0.02942 | Train Loss: 0.3504 | Train Acc: 87.98% | Val Loss: 0.3811 | Val Acc: 86.50% | Best Val Acc: 86.64%
Epoch [128/200] | LR: 0.02871 | Train Loss: 0.3416 | Train Acc: 88.40% | Val Loss: 0.4175 | Val Acc: 85.66% | Best Val Acc: 86.64%
Epoch [129/200] | LR: 0.02800 | Train Loss: 0.3402 | Train Acc: 88.21% | Val Loss: 0.4265 | Val Acc: 85.02% | Best Val Acc: 86.64%
Epoch [130/200] | LR: 0.02730 | Train Loss: 0.3325 | Train Acc: 88.65% | Val Loss: 0.4082 | Val Acc: 86.20% | Best Val Acc: 86.64%
Epoch [131/200] | LR: 0.02660 | Train Loss: 0.3342 | Train Acc: 88.58% | Val Loss: 0.3987 | Val Acc: 86.08% | Best Val Acc: 86.64%
Epoch [132/200] | LR: 0.02591 | Train Loss: 0.3298 | Train Acc: 88.76% | Val Loss: 0.3702 | Val Acc: 87.44% | Best Val Acc: 87.44%
Epoch [133/200] | LR: 0.02523 | Train Loss: 0.3254 | Train Acc: 88.82% | Val Loss: 0.3720 | Val Acc: 87.32% | Best Val Acc: 87.44%
Epoch [134/200] | LR: 0.02455 | Train Loss: 0.3225 | Train Acc: 89.03% | Val Loss: 0.3854 | Val Acc: 86.76% | Best Val Acc: 87.44%
Epoch [135/200] | LR: 0.02388 | Train Loss: 0.3107 | Train Acc: 89.36% | Val Loss: 0.3993 | Val Acc: 86.38% | Best Val Acc: 87.44%
Epoch [136/200] | LR: 0.02321 | Train Loss: 0.3076 | Train Acc: 89.54% | Val Loss: 0.4319 | Val Acc: 85.54% | Best Val Acc: 87.44%
Epoch [137/200] | LR: 0.02255 | Train Loss: 0.3076 | Train Acc: 89.55% | Val Loss: 0.3521 | Val Acc: 87.98% | Best Val Acc: 87.98%
Epoch [138/200] | LR: 0.02190 | Train Loss: 0.3000 | Train Acc: 89.62% | Val Loss: 0.3638 | Val Acc: 87.70% | Best Val Acc: 87.98%
Epoch [139/200] | LR: 0.02125 | Train Loss: 0.2982 | Train Acc: 89.69% | Val Loss: 0.4042 | Val Acc: 86.02% | Best Val Acc: 87.98%
Epoch [140/200] | LR: 0.02061 | Train Loss: 0.2899 | Train Acc: 90.04% | Val Loss: 0.3494 | Val Acc: 88.52% | Best Val Acc: 88.52%
Epoch [141/200] | LR: 0.01998 | Train Loss: 0.2860 | Train Acc: 90.10% | Val Loss: 0.3641 | Val Acc: 87.32% | Best Val Acc: 88.52%
Epoch [142/200] | LR: 0.01935 | Train Loss: 0.2845 | Train Acc: 90.26% | Val Loss: 0.3287 | Val Acc: 89.02% | Best Val Acc: 89.02%
Epoch [143/200] | LR: 0.01874 | Train Loss: 0.2779 | Train Acc: 90.45% | Val Loss: 0.3676 | Val Acc: 87.42% | Best Val Acc: 89.02%
Epoch [144/200] | LR: 0.01813 | Train Loss: 0.2742 | Train Acc: 90.60% | Val Loss: 0.3164 | Val Acc: 89.06% | Best Val Acc: 89.06%
Epoch [145/200] | LR: 0.01753 | Train Loss: 0.2664 | Train Acc: 90.84% | Val Loss: 0.3582 | Val Acc: 87.58% | Best Val Acc: 89.06%
Epoch [146/200] | LR: 0.01693 | Train Loss: 0.2620 | Train Acc: 90.93% | Val Loss: 0.3104 | Val Acc: 88.92% | Best Val Acc: 89.06%
Epoch [147/200] | LR: 0.01635 | Train Loss: 0.2567 | Train Acc: 91.36% | Val Loss: 0.3344 | Val Acc: 88.54% | Best Val Acc: 89.06%
Epoch [148/200] | LR: 0.01577 | Train Loss: 0.2512 | Train Acc: 91.38% | Val Loss: 0.3363 | Val Acc: 88.34% | Best Val Acc: 89.06%
Epoch [149/200] | LR: 0.01520 | Train Loss: 0.2467 | Train Acc: 91.43% | Val Loss: 0.3089 | Val Acc: 89.54% | Best Val Acc: 89.54%
Epoch [150/200] | LR: 0.01464 | Train Loss: 0.2428 | Train Acc: 91.56% | Val Loss: 0.3260 | Val Acc: 88.92% | Best Val Acc: 89.54%
Epoch [151/200] | LR: 0.01409 | Train Loss: 0.2402 | Train Acc: 91.63% | Val Loss: 0.3355 | Val Acc: 88.76% | Best Val Acc: 89.54%
Epoch [152/200] | LR: 0.01355 | Train Loss: 0.2311 | Train Acc: 92.06% | Val Loss: 0.3605 | Val Acc: 88.12% | Best Val Acc: 89.54%
Epoch [153/200] | LR: 0.01302 | Train Loss: 0.2250 | Train Acc: 92.20% | Val Loss: 0.3135 | Val Acc: 89.34% | Best Val Acc: 89.54%
Epoch [154/200] | LR: 0.01249 | Train Loss: 0.2205 | Train Acc: 92.42% | Val Loss: 0.3403 | Val Acc: 89.06% | Best Val Acc: 89.54%
Epoch [155/200] | LR: 0.01198 | Train Loss: 0.2149 | Train Acc: 92.61% | Val Loss: 0.3352 | Val Acc: 88.48% | Best Val Acc: 89.54%
Epoch [156/200] | LR: 0.01147 | Train Loss: 0.2135 | Train Acc: 92.64% | Val Loss: 0.3062 | Val Acc: 89.34% | Best Val Acc: 89.54%
Epoch [157/200] | LR: 0.01098 | Train Loss: 0.2075 | Train Acc: 92.92% | Val Loss: 0.2824 | Val Acc: 90.38% | Best Val Acc: 90.38%
Epoch [158/200] | LR: 0.01049 | Train Loss: 0.1965 | Train Acc: 93.08% | Val Loss: 0.3099 | Val Acc: 89.94% | Best Val Acc: 90.38%
Epoch [159/200] | LR: 0.01002 | Train Loss: 0.1892 | Train Acc: 93.53% | Val Loss: 0.2823 | Val Acc: 90.56% | Best Val Acc: 90.56%
Epoch [160/200] | LR: 0.00955 | Train Loss: 0.1905 | Train Acc: 93.38% | Val Loss: 0.2862 | Val Acc: 90.50% | Best Val Acc: 90.56%
Epoch [161/200] | LR: 0.00909 | Train Loss: 0.1816 | Train Acc: 93.70% | Val Loss: 0.2593 | Val Acc: 91.12% | Best Val Acc: 91.12%
Epoch [162/200] | LR: 0.00865 | Train Loss: 0.1746 | Train Acc: 93.86% | Val Loss: 0.2832 | Val Acc: 91.06% | Best Val Acc: 91.12%
Epoch [163/200] | LR: 0.00821 | Train Loss: 0.1646 | Train Acc: 94.32% | Val Loss: 0.2761 | Val Acc: 90.82% | Best Val Acc: 91.12%
Epoch [164/200] | LR: 0.00778 | Train Loss: 0.1633 | Train Acc: 94.40% | Val Loss: 0.2865 | Val Acc: 90.66% | Best Val Acc: 91.12%
Epoch [165/200] | LR: 0.00737 | Train Loss: 0.1577 | Train Acc: 94.54% | Val Loss: 0.2789 | Val Acc: 90.64% | Best Val Acc: 91.12%
Epoch [166/200] | LR: 0.00696 | Train Loss: 0.1549 | Train Acc: 94.58% | Val Loss: 0.2734 | Val Acc: 90.92% | Best Val Acc: 91.12%
Epoch [167/200] | LR: 0.00657 | Train Loss: 0.1435 | Train Acc: 94.97% | Val Loss: 0.2599 | Val Acc: 91.14% | Best Val Acc: 91.14%
Epoch [168/200] | LR: 0.00618 | Train Loss: 0.1425 | Train Acc: 95.07% | Val Loss: 0.2699 | Val Acc: 90.90% | Best Val Acc: 91.14%
Epoch [169/200] | LR: 0.00581 | Train Loss: 0.1306 | Train Acc: 95.51% | Val Loss: 0.2600 | Val Acc: 91.50% | Best Val Acc: 91.50%
Epoch [170/200] | LR: 0.00545 | Train Loss: 0.1244 | Train Acc: 95.80% | Val Loss: 0.2748 | Val Acc: 91.22% | Best Val Acc: 91.50%
Epoch [171/200] | LR: 0.00510 | Train Loss: 0.1232 | Train Acc: 95.75% | Val Loss: 0.2493 | Val Acc: 91.74% | Best Val Acc: 91.74%
Epoch [172/200] | LR: 0.00476 | Train Loss: 0.1154 | Train Acc: 95.97% | Val Loss: 0.2630 | Val Acc: 91.50% | Best Val Acc: 91.74%
Epoch [173/200] | LR: 0.00443 | Train Loss: 0.1093 | Train Acc: 96.28% | Val Loss: 0.2543 | Val Acc: 91.66% | Best Val Acc: 91.74%
Epoch [174/200] | LR: 0.00411 | Train Loss: 0.1017 | Train Acc: 96.44% | Val Loss: 0.2587 | Val Acc: 91.92% | Best Val Acc: 91.92%
Epoch [175/200] | LR: 0.00381 | Train Loss: 0.0979 | Train Acc: 96.64% | Val Loss: 0.2549 | Val Acc: 91.72% | Best Val Acc: 91.92%
Epoch [176/200] | LR: 0.00351 | Train Loss: 0.0920 | Train Acc: 96.93% | Val Loss: 0.2546 | Val Acc: 91.74% | Best Val Acc: 91.92%
Epoch [177/200] | LR: 0.00323 | Train Loss: 0.0882 | Train Acc: 96.95% | Val Loss: 0.2371 | Val Acc: 92.16% | Best Val Acc: 92.16%
Epoch [178/200] | LR: 0.00296 | Train Loss: 0.0812 | Train Acc: 97.24% | Val Loss: 0.2425 | Val Acc: 92.44% | Best Val Acc: 92.44%
Epoch [179/200] | LR: 0.00270 | Train Loss: 0.0776 | Train Acc: 97.44% | Val Loss: 0.2358 | Val Acc: 92.74% | Best Val Acc: 92.74%
Epoch [180/200] | LR: 0.00245 | Train Loss: 0.0705 | Train Acc: 97.65% | Val Loss: 0.2316 | Val Acc: 92.54% | Best Val Acc: 92.74%
Epoch [181/200] | LR: 0.00221 | Train Loss: 0.0681 | Train Acc: 97.83% | Val Loss: 0.2377 | Val Acc: 92.64% | Best Val Acc: 92.74%
Epoch [182/200] | LR: 0.00199 | Train Loss: 0.0634 | Train Acc: 97.92% | Val Loss: 0.2416 | Val Acc: 92.58% | Best Val Acc: 92.74%
Epoch [183/200] | LR: 0.00177 | Train Loss: 0.0593 | Train Acc: 98.09% | Val Loss: 0.2418 | Val Acc: 92.62% | Best Val Acc: 92.74%
Epoch [184/200] | LR: 0.00157 | Train Loss: 0.0531 | Train Acc: 98.31% | Val Loss: 0.2416 | Val Acc: 92.74% | Best Val Acc: 92.74%
Epoch [185/200] | LR: 0.00138 | Train Loss: 0.0516 | Train Acc: 98.40% | Val Loss: 0.2445 | Val Acc: 92.74% | Best Val Acc: 92.74%
Epoch [186/200] | LR: 0.00120 | Train Loss: 0.0499 | Train Acc: 98.52% | Val Loss: 0.2392 | Val Acc: 92.80% | Best Val Acc: 92.80%
Epoch [187/200] | LR: 0.00104 | Train Loss: 0.0474 | Train Acc: 98.54% | Val Loss: 0.2327 | Val Acc: 93.22% | Best Val Acc: 93.22%
Epoch [188/200] | LR: 0.00089 | Train Loss: 0.0446 | Train Acc: 98.66% | Val Loss: 0.2417 | Val Acc: 92.96% | Best Val Acc: 93.22%
Epoch [189/200] | LR: 0.00074 | Train Loss: 0.0415 | Train Acc: 98.78% | Val Loss: 0.2427 | Val Acc: 93.04% | Best Val Acc: 93.22%
Epoch [190/200] | LR: 0.00062 | Train Loss: 0.0406 | Train Acc: 98.74% | Val Loss: 0.2444 | Val Acc: 93.04% | Best Val Acc: 93.22%
Epoch [191/200] | LR: 0.00050 | Train Loss: 0.0388 | Train Acc: 98.88% | Val Loss: 0.2477 | Val Acc: 92.86% | Best Val Acc: 93.22%
Epoch [192/200] | LR: 0.00039 | Train Loss: 0.0382 | Train Acc: 98.89% | Val Loss: 0.2428 | Val Acc: 93.16% | Best Val Acc: 93.22%
Epoch [193/200] | LR: 0.00030 | Train Loss: 0.0368 | Train Acc: 98.90% | Val Loss: 0.2459 | Val Acc: 92.92% | Best Val Acc: 93.22%
Epoch [194/200] | LR: 0.00022 | Train Loss: 0.0361 | Train Acc: 98.92% | Val Loss: 0.2428 | Val Acc: 92.88% | Best Val Acc: 93.22%
Epoch [195/200] | LR: 0.00015 | Train Loss: 0.0352 | Train Acc: 98.97% | Val Loss: 0.2435 | Val Acc: 92.92% | Best Val Acc: 93.22%
Epoch [196/200] | LR: 0.00010 | Train Loss: 0.0356 | Train Acc: 98.95% | Val Loss: 0.2450 | Val Acc: 92.94% | Best Val Acc: 93.22%
Epoch [197/200] | LR: 0.00006 | Train Loss: 0.0342 | Train Acc: 99.02% | Val Loss: 0.2418 | Val Acc: 93.00% | Best Val Acc: 93.22%
Epoch [198/200] | LR: 0.00002 | Train Loss: 0.0331 | Train Acc: 99.11% | Val Loss: 0.2458 | Val Acc: 92.80% | Best Val Acc: 93.22%
Epoch [199/200] | LR: 0.00001 | Train Loss: 0.0336 | Train Acc: 99.06% | Val Loss: 0.2420 | Val Acc: 92.96% | Best Val Acc: 93.22%
Epoch [200/200] | LR: 0.00000 | Train Loss: 0.0350 | Train Acc: 98.99% | Val Loss: 0.2452 | Val Acc: 92.86% | Best Val Acc: 93.22%
----- Finished Training -----
Best Validation Accuracy: 93.22% (Epoch 187)
----- Final Test Result -----
Test Loss: 0.2592
Final Test Accuracy: 92.54%