PyTorch에서 eval과 no_에 대해 얘기해 볼게요.grad의 관계

4196 단어 PyTorchevalno grad

우선 이 두 가지는 본질적인 차이가 있다


model.eval () 은 모델 내의 각layer가 eval 모드로 작업하는 것을 알리는 데 사용됩니다.이 조작은 주로dropout과batchnorm 등 훈련 모드에서 서로 다른 조작을 해야 하는 특수layer에 대응하는 것이다.훈련과 테스트 때 모두 오픈할 수 있습니다.
torch.no_grad () 는 자동 유도 엔진이 유도 조작을 하지 말라고 알려 줍니다.이 조작의 의의는 계산을 가속화하고 메모리를 절약하는 데 있다.그러나gradient가 없기 때문에backward를 진행할 방법이 없습니다.그래서 테스트 때만 열 수 있어요.
그래서 evaluate를 할 때 두 가지를 동시에 사용해야 한다.

model = ...
dataset = ...
loss_fun = ...

# training
lr=0.001
model.train()
for x,y in dataset:
 model.zero_grad()
 p = model(x)
 l = loss_fun(p, y)
 l.backward()
 for p in model.parameters():
  p.data -= lr*p.grad
 
# evaluating
sum_loss = 0.0
model.eval()
with torch.no_grad():
 for x,y in dataset:
  p = model(x)
  l = loss_fun(p, y)
  sum_loss += l
print('total loss:', sum_loss)
별도no_grad는 함수로 수식자로도 사용할 수 있어 코드를 간소화할 수 있다.

def train(model, dataset, loss_fun, lr=0.001):
 model.train()
 for x,y in dataset:
  model.zero_grad()
  p = model(x)
  l = loss_fun(p, y)
  l.backward()
  for p in model.parameters():
   p.data -= lr*p.grad
 
@torch.no_grad()
def test(model, dataset, loss_fun):
 sum_loss = 0.0
 model.eval()
 for x,y in dataset:
  p = model(x)
  l = loss_fun(p, y)
  sum_loss += l
 return sum_loss

# main block:
model = ...
dataset = ...
loss_fun = ...

# training
train()
# test
sum_loss = test()
print('total loss:', sum_loss)
보충:pytorch 중 모델.train、model.eval 및 torch.no_grad의 용법

1、model.train()


BatchNormalization 및 Dropout 활성화
model.train () 은 모델을 훈련 모드로 바꿉니다. 이때dropout과batchnormalization의 조작은 훈련에서 네트워크의 과합을 방지하는 문제를 일으킵니다.

2、model.eval()


BatchNormalization 및 Dropout 사용 안 함
model.eval (), Pytorch는 자동으로 BN과 Drop Out을 고정시키고 훈련된 값을 사용합니다.그렇지 않으면 테스트의batch_크기가 너무 작아서 BN 층에 의해 생성된 그림의 색깔이 크게 틀리기 쉽다
train 샘플을 훈련한 후 생성된 모델 모델은 샘플을 테스트하는 데 사용됩니다.모델 (test) 전에 모델을 추가해야 합니다.eval (), 그렇지 않으면 입력 데이터가 있습니다. 훈련을 하지 않아도 권한 값이 바뀝니다.이것은 모델에batchnormalization층이 가지고 있는 성질이다.
훈련과 테스트를 할 때 왜 이러는지 다음 두 단락에서 이해할 수 있다.
훈련할 때 하나의batch내mean과var를 계산하지만 작은batch작은batch의 훈련이기 때문에 가중치나 동량의 형식으로 각각batch의mean과var를 누적한다. 즉, 현재의batch를 계산할 때 사실 현재의 권중은 0.1을 차지하고 이전에 훈련한 모든 권중은 0.9를 차지한다.이렇게 하는 좋은 점은 어떤 배치가 너무 기발해서 훈련이 불안정하지 않다는 것이다.
자, 이제 훈련이 끝났다고 가정하면 전체 훈련집에서도 최종적인'mean과 var'를 얻었고 BN층 안의 매개 변수도 공부했다(학습을 지정하면). 지금은 테스트를 해야 한다. 테스트를 할 때 종종 한 장의 그림으로 측정한다. 이때batch가 없으면 단독의 데이터에mean과 var를 하는 것은 의미가 없다. 그러면 어떻게 해야 하는가.실제로 테스트할 때 BN에서 쓰는 mean과 var가 바로 훈련이 끝난 mean입니다.final 및 val_final. 테스트할 때 BN이 하나의 변환이라고 할 수 있다.그러므로pytorch를 사용할 때 이 점을 주의하고 훈련하기 전에 모델이 있어야 한다.train () 은 네트워크가 현재 훈련 모드를 열었음을 알려줍니다. eval에서'모델'을 사용해야 합니다.eval ()"은 네트워크가 이제 테스트 모드에 들어간다는 것을 알려주는 데 사용됩니다.두 가지 모드에서 BN의 역할은 다르기 때문입니다.

3、torch.no_grad()


이 문장의 역할은 테스트를 할 때 계단식 계산을 하지 않고 테스트를 할 때 현존의 점용을 효과적으로 줄이고 현존이 넘치지 않도록 하는 것이다.
이 문장은 통상적으로 네트워크가 예측하는 그 코드에 덧붙인다.

4.pytorch에서 모델.eval() 및 "with torch.no_grad() 차이점


양자 구별


PyTorch에서 validation을 진행할 때 모델을 사용합니다.eval () 테스트 모드로 전환합니다. 이 모드에서
주로dropout층과batchnorm층이 train과val모드에서 전환되는 것을 알립니다
train 모드에서dropout 네트워크 층은 설정된 매개 변수 p에 따라 활성화 단원의 확률을 보류합니다(유보 확률 =p).batchnorm층은 데이터의mean과var 등 매개 변수를 계속 계산하고 업데이트합니다.
val 모드에서dropout층은 모든 활성화 단원을 통과하게 하고batchnorm층은mean과var의 계산과 업데이트를 멈추고 훈련 단계에서 배운 mean과var값을 직접 사용합니다.
이 모델은 각 층의gradient 계산 행위에 영향을 주지 않습니다. 즉gradient 계산과 저장은training 모델과 마찬가지로 반전(backprobagation)만 하지 않습니다.
with torch.zero_grad()는 주로 autograd 모듈의 작업을 멈추고 메모리를 가속화하고 절약하는 역할을 한다. 구체적인 행위는gradient 계산을 멈추고 GPU 산력과 메모리를 절약하는 것이지만dropout과batchnorm층의 행위에 영향을 주지 않는다.

장면 사용


메모리 크기와 시간 계산에 신경 쓰지 않는다면 모델만 사용하세요.eval () 은 정확한validation 결과를 얻을 수 있습니다.with torch.zero_grad()는 gpu 공간을 더욱 가속화하고 절약하는 것이다. (gradient를 계산하고 저장하지 않기 때문에) 더 빨리 계산할 수도 있고, 더 큰batch를 뛰어서 테스트할 수도 있다.
이상의 개인적인 경험으로 여러분께 참고가 되었으면 좋겠습니다. 또한 많은 응원 부탁드립니다.만약 잘못이 있거나 완전한 부분을 고려하지 않으신다면 아낌없이 가르침을 주시기 바랍니다.

좋은 웹페이지 즐겨찾기