꺼내먹는지식 준

Training, Inference - Loss, Optimizer, Metric 본문

카테고리 없음

Training, Inference - Loss, Optimizer, Metric

알 수 없는 사용자 2022. 2. 22. 15:45

데이터 설계, 모델 설계 $\rightarrow$ Training 

 

모델을 만들어서 학습과 inference를 해보자. 

 

 

Training에 영향을 끼치는 3가지 요소 

Loss

(오차) 역전파 

Loss도 사실 nn.family 

 

Loss 가 특정 목적에 따라 다르게 변경될 수 있다는 점 유의 

학습과정 파라미터 업데이트과정도 바뀌게 된다.

nn.Loss 도 loss class를 가지고 있고 각 loss class는 forward를 가지고 있다. (즉 연결될 수 있다.)

 

 

모델의 파라미터를 업데이트 하는 것이 목적 

근데 왜 loss.backward 일까? 

이는 loss 도 nn.Module을 상속했기 때문이다. 

foward 를 거쳐 출력 된 output 의 연산이 loss이기에, 연결되어있어 

loss.backward()로 접근이 가능하다. 

 

 

다른 loss

사실상 loss는 몇가지 추가 term을 더해 약간 씩 다른 역할을 하는 loss를 만들어 낼 수 있다. 

이 중 대표적인 예시로 

 

Focal Loss 

class imbalance문제가 있는 경우, 맞춘 확률이 높은 class는 조금의 loss를, 

맞춘 확률이 낮은 class에는 loss를 더 높게 부여한다. 

 

Label smoothin Loss가 있다. 

class target label을 onehot ([0,1,0,0,...])으로 표현하기 보다는 조금 soft하게 표현해서 일반화 성능을 높이기 위함이다. ([0.025,0.9,0.025, 0.025, ...])

 

 

Loss custom 

결국 loss도 nn.module을 상속하기에, custom을 해줄 수 있다. 문제 정의에 따라 실험을 해봐야 한다. 

 

 

Optimizer 

 

Learning rate를 동적으로 조절하자. (LR scheduler)

 

LR scheduler

StepLR 

 

특정 step마다 LR 감소 (step이 커질수록)

 

CosineAnnealingLR 

코사인 함수 형태로 LR을 급격히 변경 

(이상해 보이지만, 변화를 급격하게 줄 수 있다. 이로 인해 local minima에 잘 빠지지 않고 잘 빠져나온다. )

 

ReduceLROnPlateau

성능의 향상이 없을 때 LR 감소

모니터링 할 때, 대상을 바라보다가 몇번 step동안 향상이 없으면 LR 을 줄여나가는 방식, 보통 일반적으로 가장 많이 쓴다. 

(안정적 학습)

 

$\rightarrow$ 정답이란 없다. 다 실험을 통해 확인해봐야한다. 

 

Metric

학습에 직접적인 영향을 끼치지는 않지만, 결과를 객관적 지표로 보기 위해서는 metric이 필수이다. 

loss 가 감소한다해도 모델이 일반적으로 어떤 성능을 가질 것이다 라는 객관적 지표로 보기에는 어렵다. 

 

사용 지표 

Metric 의 종류가 다양하다. 

object detection만 해도 기준이 필요하다. IoU등.. 

 

class 가 imbalance할 때는 accuracy보다는 F1-score  

 

Metric의 특성을 추후 더 알아보자. 언제 쓰이나 알면 좋다. 

경험을 좀 쌓아놓아야, 어떤 metric 쓸지 바로 감이 온다. 

 

오른쪽 200 개중 100개 다틀려놓고 잘 맞춘다고 하는게 이상하다. 

balance가 안맞는다. 이때는 F1-score

 

 

Training 과정 & inference 

trainin일 이어나면 어떤변호가 있을까? 

각 동작 원리를 라인 바이 라인으로 이해하여 응용해보자. 

 

학습 진행 cycle

에서 

두번째 batch 부터 zero_grad  를 하지 않으면 그전 batch의 파라미터의 grad가 그대로 남는다. 

계속 쓰는게 좋을까 초기화가 좋을까?

 

통상적으로 

minibatch 내에서만 발생한 loss gradient 업데이트를 하지, 일반적으로 이 전  단계는 사용하지 않는다. 

 

default 는 batch_grd = False 

 

어떻게 동작하는지 알기 위하여, 여러 작업을 해보자. 

 

loss = criterion(outputs, labels)

 

chain 생성

 

backward 후 grad에 값이 업데이트 되어 있다. 

최종 목표는 model paramter 값이 변해야 한다. 

 

loss는 grad 값만 update한다. 

그러면 parameter로 적용은 누가 시키는가?

optimzer. (optimizer가 선언 후)

 

optimizer.step() 을 통해 input으로 받은 parameter를 확인하여 gradient를 업데이트 한다. 

 

Training Process는 여기까지 이다. 

 

추가 사항 

 

Gradient Accumulation 

응용 과정을 살펴보자. 

mini batch 학습 자체가 기본 사이즈 작업만큼 돌려서 배치의 분포를 바탕으로 조금씩 학습을 한다. 

매번 batch size를 가지고 작업을 하는데, GPU memory는 한정적이다.

어떤 task의 경우 batch 사이즈가 중요한 경우도 있다.(GPU 사정으로 인해) 이 때, 작은 배치가 분포를 다 못담을 수도 있다. 

 

일반적으로 GPU에 메모리가 많다고 하면 가능하겠지만, 못 늘리면 batch size를 늘리는 것과 비슷한 효과를 줄 수는 없을까?  

 

그냥 기존 방법도 다시 읽고 잘 이해했나 점검하게 정리해보자. 

 

기존 방법 

 

하나의 batch 마다 batch가 만들어내는 loss 를 바탕으로 backward를 하면서 model paramter 에 업데이트 되는 grad (parameter값이 변경된것이 아니라 grad에 저장된 것)를 가지고 optimizer가 step 

 

새로운 방법 

매 배치마다 업데이트 하는게 아니라, 3 ~ 4번째마다 optimizer가 step을 하도록 하면 어떨까? loss 는 중첩적으로 쌓이고, step마다 알고리즘 적으로 구현을 했을 때, 그때마다 optimizer가 쌓인 loss를 step을 밟아 parameter를 업데이트 하고 학습을 해나갈 수 있다. 이 것이 gradient accumulation  

 

optimizer step을 몇번째마다 할지만 정해주고, step도 zero grad도 이에 맞게 한다. 

 

하나 하나 과정을 이해하면, 변칙적으로 응용하는 것이 훨씬 간단하다. 

 

pytorch의 pythonic 한 특징 덕에 너무 간단하다. 

 

Inference Process 

간단 구성! 

 

model.eval()

: drop out, BatchNorm 이나 이런 것들 멈추기 위해서. 무조건 써야 한다. 

 

with torch.no_grad() 

inference 시, grad 업데이트가 안되도록 

 

# torch.no_grad() just disables the tracking of any calculations required to later calculate a gradient.

forward 과정에서 gradient가 발생해도, 업데이트가 되지는 않는다. 그러나 tracking에 memory가 사용된다고 한다. 

 

#torch.no_grad() basically skips the gradient calculation over the weights. That means you are not changing any weight in the specified layers. If you are trainin pre-trained model, it's ok to use torch.no_grad() on all the layers except fully connected layer or classifier layer.

 

Pytorch 정규 문서 

#Disabling gradient calculation is useful for inference, when you are sure that you will not call Tensor.backward(). It will reduce memory consumption for computations that would otherwise have requires_grad=True.

 

Validation 확인 

추론 과정에 validation 셋이 들어가면 그게 검증이다. 

 

Checkpoint 

 

그냥 결과물들 중도 저장하면 된다.

validation 중, 가장 좋은 결과이면 저장 시키는 것이 좋다. 

unseen data이기 때문에. 

 

최종 output, submission 형태로 변환

id image를 무슨 클래스로 분류했는가가 제출 output 

 

Pytorch Lightning 

코드 베이스 생성이 안어려워도 귀찮고, 피곤하다. 

그런 문제를 해결해주는 것이 Pytorch Lightning 

 

대부분의 프로세스를 하나의 클래스로

간단하게 정리해준다. 

 

fit 이라는 단어하나로 정리. 

생산성 측면에서는 빠르나, 충분한 이해가 바탕이 되지 않은 상태에서는 lightning 이 오히려 독이 된다. 

 

코드로부터 머신러닝 프로세스를 배우고, 자유롭게 응용 가능하다. 

 

Comments