def training(epoch, model, trainloader, validloader):
correct = 0
total = 0
running_loss = 0
model.train()
for b in trainloader:
x, y = b.text, b.label
x, y = x.to(device), y.to(device) # 반드시 모델과 같은 device
y_pred = model(x)
loss = loss_fn(y_pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
with torch.no_grad(): # 추론
y_pred = torch.argmax(y_pred, dim=1)
correct += (y_pred == y).sum().item()
total += y.size(0)
running_loss += loss.item()
epoch_loss = running_loss / len(trainloader.dataset)
epoch_acc = correct / total
valid_correct = 0
valid_total = 0
valid_running_loss = 0
model.eval()
with torch.no_grad():
for b in validloader:
x, y = b.text, b.label
x, y = x.to(device), y.to(device)
y_pred = model(x)
loss = loss_fn(y_pred, y)
y_pred = torch.argmax(y_pred, dim=1)
valid_correct += (y_pred == y).sum().item()
valid_total += y.size(0)
valid_running_loss += loss.item()
epoch_valid_loss = valid_running_loss / len(validloader.dataset)
epoch_valid_acc = valid_correct / valid_total
print('epoch: ', epoch,
'loss: ', round(epoch_loss, 3),
'accuracy:', round(epoch_acc, 3),
'valid_loss: ', round(epoch_valid_loss, 3),
'valid_accuracy:', round(epoch_valid_acc, 3)
)
return epoch_loss, epoch_acc, epoch_valid_loss, epoch_valid_acc
- 모델 학습을 위한 함수는 DataLoader에서 데이터를 가져와서 모델에 적용한 후, 손실 함수를 적용하여 오차를 구하고 optimizer를 이용하여 파라미터(가중치, 바이어스)를 업데이트
- 일반적인 신경망 학습의 단계
- 순방향 전파 : 입력 데이터를 모델을 통해 전달하여 예측
- 손실 계산
- 역전파 : 모델의 매개변수에 대한 손실의 그레이디언트를 계산 → `loss.backward()`
- 최적화 : 계산된 그레이디언트를 기반으로 모델의 매개변수를 업데이트 → `optimizer.step()`
- `model.train()`과 `model.eval()` : 학습할 때와 추론할 때 다르게 동작하는 Layer들을 Training, Evaluation(Inference) mode로 변환
- `optimizer.zero_grad()` : 모델의 기울기(gradient)를 초기화하는 역할
- 모델 내의 모든 학습 가능한 매개변수들의 기울기를 0으로 초기화하여 이전 단계의 기울기가 현재 단계의 모델 업데이트에 관여하지 않도록 함
- 딥러닝에서는 mini batch + loop 조합을 통해 파라미터들을 업데이트하는데 한 루프에서 역전파를 통해 `.grad` 값에 변화도가 저장된 것을 다음 루프에서 초기화시켜야 학습이 제대로 진행
- `loss.backward()` : 역전파를 수행
- `requires_grad`가 True로 설정된 모든 매개변수에 대한 손실의 gradient 계산
- `optimizer.step()` : 역전파 과정에서 계산한 그레이디언트를 기반으로 모델의 매개변수를 업데이트
- `torch.no_gard()` : 파이토치의 `Autograd Engine`을 비활성하여 Gradient 계산을 하지 않아 파라미터 또한 업데이트 x
- 모델을 사용하여 예측을 수행하는 `추론(Inference)` 과정에서 그레이디언트를 계산하거나 파라미터를 업데이트할 필요가 없으므로 이를 통해 계산 효율성을 향상
- `검증(validation)` 혹은 `테스트(test)` 과정에서도 동일
https://tigris-data-science.tistory.com/entry/PyTorch-modeltrain-vs-modeleval-vs-torchnograd
https://velog.io/@kjb0531/zerograd%EC%9D%98-%EC%9D%B4%ED%95%B4
딥러닝 파이토치 교과서