model.eval()과 torch.no_grad()

#pytorch#evaluation

Pytorch의 모델 평가 단계에서 거의 항상 같이 등장하는 model.eval()torch.no_grad()를 정리해봤다.

model.eval()#

model.eval()은 모델을 평가, 즉 Evaluation에 최적화된 상태로 만드는 과정이다. Training 과정에는 model.train()이 사용된다. 이 둘은 특정 레이어의 동작을 바꾼다.

  • model.train() : dropout 레이어batchnorm 레이어모두 활성화시킨다.
  • model.eval() : dropout 레이어를 비활성화하고, batchnorm도 학습 중에 쓰던 배치 통계 대신 모델이 학습하며 축적해온 running_mean, running_var를 사용한다.

평가 시 dropout과 batchnorm을 끄는 이유#

평가할 때 dropout이 켜져 있으면 매번 결과가 달라지고, batchnorm이 현재 배치 통계를 쓰면 평가가 일관되지 않는다. 그래서 일관된 평가를 위해 eval()을 호출한다.

Dropout이란?

torch.no_grad()#

torch.no_grad()는 autograd 엔진을 꺼서 기울기를 계산하지 않도록 만든다. 평가에는 파라미터 업데이트가 필요 없기 때문에 기울기를 계산할 이유가 없다. 기울기 계산을 끄면 메모리도 아끼고 속도도 빨라진다.

model.eval()
with torch.no_grad():
    for x, t in test_loader:
        pred = model(x)
        # 평가 코드

둘은 다른 일을 한다#

이름이 비슷해서 헷갈리지만 역할이 다르다.

  • model.eval(): dropout, batchnorm 같은 레이어의 동작을 평가 모드로 바꾼다.
  • torch.no_grad(): 기울기 계산 자체를 끈다.

그래서 평가할 때는 보통 둘을 함께 사용한다. eval()만 하고 no_grad()를 빼면 기울기가 불필요하게 계산되고, no_grad()만 하고 eval()을 빼면 dropout/batchnorm이 훈련 모드로 동작해 평가가 부정확해진다.

댓글