본문 바로가기
ML&DATA/책 & 강의

Deep Learning with PyTorch - Ch5

by sun__ 2022. 3. 26.

Ch5. The Mechanics of learning

fit the data = make the argorithm learn from data

 

5.2 Learning is just parameter estimation

input data, 라벨(ground truth), 가중치의 초기값이 있을 때, 입력 데이터는 모델에 forward pass하고 결과 값과 라벨의 에러를 계산한다. 에러가 줄어드는 방향으로 기울기(gradient)가 역전파되면서 가중치가 업데이트된다. 이 과정은 에러가 특정치 이하로 떨어질 때까지 반복한다.

 

 

5.3 Less loss is what we want

loss function의 값이 최소화되는 파라미터를 찾아가는 과정을 학습이라고 함.

 

5.4 Down along the gradient

어떻게 찾아가는가? gradient descent +  back propagation이 핵심이다.

 

5.5 PyTorch's autograd: Backpropagating all things

뉴럴네트워크의 모든 연산과 파라미터 그리고 역전파값은 연산그래프로 나타낼 수 있다. 파이토치 내부적으로 연산그래프를 활용하는 것 처럼 서술함. 참고(https://stellarway.tistory.com/21?category=883928)

optimizer = optim.SGD([params], lr=learning_rate)

def training_loop(n_epochs, optimizer, params, train_t_u, val_t_u,
                  train_t_c, val_t_c):
    for epoch in range(1, n_epochs + 1):
        train_t_p = model(train_t_u, *params)
        train_loss = loss_fn(train_t_p, train_t_c)
        with torch.no_grad():
            val_t_p = model(val_t_u, *params)
            val_loss = loss_fn(val_t_p, val_t_c)
            assert val_loss.requires_grad == False
        optimizer.zero_grad()
        train_loss.backward()
        optimizer.step()



torch의 autograd는 nn의 forward expression만 있으면 자동으로 파라미터들의 gradient를 제공한다. 텐서 정의시 'requires_grad=True'옵션을 주면 해당 텐서의 연산들의 결과 텐서들의 family tree를 추적한다.

 

loss 함수의 반환 값(텐서) .backward()를 호출하면 params.grad가 갱신된다. 이 grad값은 축적된다. 파라미터 갱신 후 zero_ 메소드 등으로 0으로 초기화하는 작업을 해줘야 한다. 위 코드에선 optimizer의 zero_grad()가 그 역할을 함. 이런 축적 방식은 복잡한 모델을 다룰 때 유연성을 제공한다.

 

no_grad() context 밑에서는 텐서 연산시 forward graph를 만들지 않는다. 

 

optimizer는 다양한 gradient descent 전략 중 어떤걸 선택할지(SGD, GD, Adam 등등)에 관련. 모든 인풋데이터를 한번에 학습하지 못할정도로 데이터가 많은 경우가 대부분이다. 순차적으로 배치단위로 처리하는데, 이 배치단위로 처리할 때도 미니배치로 나눠서 처리하는 경우가 많다. 이때 미니배치(subset)의 선택을 랜덤하게 하기도 하고, 다양한 방법이 있는 것 같다. optim모듈에 정의돼 있다. zero_grad()로  등록된 텐서의 grad를 비워주거나 step으로 등록된 텐서의 grad를 가지고 텐서를 업데이트해준다.  아래 그림에 잘 설명돼 있다.

A->B->C->D 순서대로

 

 

위 코드의 training loop에서 가변적인 부분은 optimizer와 model 뿐이다. 

 

5.5.3 Training, validation, and overfitting

인풋 샘플(배치)를 test, train, validation 세트로 나눠서 학습을 진행한다. 검증세트가 있는 이유는, epochs를 거쳐가며 모델이 train데이터에 과적합되는지를 감시하기 위함이다. 아래 그림에서,

  • A: 전혀 학습하고 있지 않음.
  • B: 과적합되는중
  • C: 이상적인 학습
  • D: 현실적으로 acceptable한 학습이 이뤄지는 중

빨강: validation loss, 파랑: training loss

 

training loss가 더이상 줄지 않는다면, 모델이 너무 단순하거나 데이터에 의미 있는 정보가 부족하기 때문이다. 

 

과적합을 피하기 위해선 regulation(규제)를 적용하여 릿지, 라쏘, 엘라스틱넷 등의 가중치 제한 테크닉을 사용하거나 조기종료를 하기도 한다. 또 다른 방법으론 input data를 인위적으로 만들어서 데이터 양을 늘리기도 한다.

 

training set에 맞추기 위한 충분한 용량을 갖는 모델과 과적합을 피하기 위한 단순한 모델 사이에 trade-off가 존재한다.

 

5.5.4 Autograd nits and switching it off

위 코드에서 train_loss와 val_loss에 들어가는 파라미터가 같은데, backward 시 autograd가 혼동하지는 않을까? 

-> train_t_u, train_t_p, train_loss 연산그래프와 val_t_u, val_t_p, val_loss 연산그래프가 분리돼 있는 형태라서 문제 없다. 

 

용도에 맞는 사용을 위해 val_loss로 backward를 호출해선 안된다. 만약 호출한다면 train-val 세트를 나누지 않은 것과 같은 결과가 나온다.

'ML&DATA > 책 & 강의' 카테고리의 다른 글

NLP with Transformers - Ch1  (0) 2022.03.28
Deep Learning with PyTorch - Ch6  (0) 2022.03.28
Deep Learning with PyTorch - ~Ch3  (0) 2022.03.16