본문 바로가기
TIL/Boostcamp AI tech

[Boostcamp]Week3-Day12. Pytorch 구조 학습 :: seoftware

by seowit 2021. 8. 18.
목차
1. 강의정리
    1-1. PyTorch - chap4. Autograd & Optimizer
    1-2. PyTorch - chap5. Dataset & Dataloader
2. 과제 - Custom Dataset
3. 피어세션 정리
4. 데일리 회고 

📜 강의 정리 

* 부스트캠프 PyTorch 강의를 맡아주신 최성철 교수님의 강의를 정리한 것 입니다.


[PyTorch] Chapter4. AutoGrad & Optimizer

 

🌈 Process 흐름과 세부 구성에 대해 알아보자.

 

1. 네트워크는 수많은 반복의 연속이다. block으로 많이 비유되는 Layer 층이 반복된다.

ResNet

2. 반복이 되는 Layer들은 torch.nn.Module로 구현할 수 있다.

  • nn.Module은 기본적으로 Input, Output, Forward, Backward를 정의해야한다. Forward는 WX+b와 같이 y_hat을 예측하기 위한 계산과정을 의미하고, Backward는 gradient 계산 과정을 담당한다. 그러나 Pytorch에서는 AutoGrad 기능을 제공하기 때문에 Backward 부분의 미분 수식 작성은 걱정하지 않아도 된다.

3. 앞서 말했던 Autograd에 대해 자세히 말하자면, 학습의 대상이 되는 weights 값을 nn.Parameter로 정의한다.

  • nn.Parameter가 nn.Module의 attribute(클래스의 변수나 메소드)가 될 때에는 required_grad=True로 지정이 되어 Autograd의 대상이 된다.
  • 코드 예시
    모델 클래스의 init 함수 안에서 이런식으로 사용되지만, 보통은 layer(Conv, Linear 등) 안에 정의되어 있어서 직접 사용할 일은 없다. 그래도 구조는 알아두자!

4. Backward

  • Backward 단계에서 loss(forward 로 나온 결과인 y_hat과 실제값인 y의 차이)와 각각의 Layer에 있는 파라미터들의 미분을 수행하고 그 값을 업데이트 한다. 구체적인 단계는 총 4단계로 나눌 수 있다.
  • 1. optimizer.zero_grad() : 이전 에폭에 계산된 gradient 값을 0으로 초기화한다. PyTorch에서는 gradient를 backward() 할 때 계속 더해주는데 초기값이 0이 아니면 의도하지 않은 결과를 얻게 된다. * gradient를 초기화하는 것이지 optimizer를 초기화하는 것이 아니고, 각 layer 별로 W와 b 값은 살아있다.
  • 2. ouputs = model(inputs) : 모델에 x 넣어주는 것
  • 3. loss = criterion(ouputs, labels) : loss를 구하는 것
  • 4. loss.backward() : loss에 대한 각 파라미터들의 미분을 구하는 것
  • 5. optimizer.step() : 파라미터 값을 업데이트. w := w - lr*dw (dw는 loss를 w로 편미분한 값)

 

+) nn.Parameters에 대해 추가하자면, Autograd 기능을 사용할 것이면 nn.Parameter를 사용하지만, backward를 직접 구현한다면 Tensor에 학습할 weights를 담아도 된다. nn.Parameter를 사용하면, 아래 사진과 같이 미분의 대상이 되는 파라미터를 볼 수 있다는 특징이 있다. Tensor를 사용하게 되면 parameters로 접근이 안되고, required_grad=True도 없다.

 


[PyTorch] Chapter5. Dataset & Dataloader

 

🌈 모델에 data가 들어가기 전(GPU에 feed 전)까지의 과정에 대해 알아보자

 

  • Dataset 클래스는 데이터의 입력 형태를 정의하는 클래스로, 데이터에 접근할 수 있는 인터페이스도 만들어줘야한다(__getItem__())
  • Transforms는 데이터 전처리하는 과정 중 하나인데, ToTensor()로 값을 넘겨주는 것과 이미지 파일을 넘겨주는 역할이 다르다.
  • Dataloader 는 특정 batch size로 데이터를 잘라서 새로운 형태로 만들어 주는 과정이다.

 

👍 Dataloader 관련 추천 포스팅 :  https://subinium.github.io/pytorch-dataloader/

 

[Pytorch] DataLoader parameter별 용도

pytorch reference 문서를 다 외우면 얼마나 편할까!!

subinium.github.io


 


👩‍💻 과제 수행 과정


❓❓ collate_fn 은 왜하지? batch size 별로 조정이 왜 필요하지?

✅ 현재 input dataset 의 형식은 (이미지1, 라벨1) (이미지2, 라벨2) 형식으로 되어 있는데, 이걸 (이미지1, 이미지2) (라벨1, 라벨2) 형태로 바꿔주는 걸 collate_fn이라고 한다. 보통 map-style 데이터셋에서 sample list를 batch 단위로 바꾸기 위해 필요한 기능이다. zero-padding이나 Variable Size 데이터 등 데이터 사이즈를 맞추기 위해 많이 사용한다. batch 별로 크기가 조금 다를 수 있어서 자리가 남는 batch에는 뒤에 0을 붙여서 size를 똑같이 맞춰준다.

 

❓❓ dataloader의 작동방식에 대한 이해가 잘 안되는데..

✅ dataloader는 dataset, sampler, collate_fn의 값을 받아서 데이터를 map-style과 iter 방식으로 생성해준다. 아래 블로그 천천히 정독하면 조금 이해가 된다.

https://hulk89.github.io/pytorch/2019/09/30/pytorch_dataset/

 

pytorch dataset 정리 · Hulk의 개인 공부용 블로그

pytorch dataset 정리 30 Sep 2019 | ml pytorch dataloader Dataset, Sampler, Dataloader Overview Dataset Data를 가지고있는 객체. __len__, __getitem__을 구현해야함 DataLoader를 통해 data를 받아올 수 있다. DataLoader Dataset을 인자

hulk89.github.io

 

❓❓ collate_fn에서 return 할 때 torch.stack이란게 쓰이는데, 이건 뭐지?

✅ 새로운 차원에 따라 텐서 시퀀스를 이어붙이는 것.

https://pytorch.org/docs/stable/generated/torch.stack.html

 

torch.stack — PyTorch 1.9.0 documentation

Shortcuts

pytorch.org

 

❓❓ batch에서 가장 긴 배열에 맞춰서 0으로 패딩하는 방법?

collate_X = torch.nn.utils.rnn.pad_sequence(collate_X, batch_first=True, padding_value=0.0)

Tensor([[0], [1, 1]]) 이런 tensor를 Tensor([[0, 0], [1, 1]]) 이런 형태로 가장 긴 배열의 크기에 맞추어서 0으로 값을 채워주려고 할 때, pad_sequence를 사용할 수 있다. T가 가장 긴 배열의 길이이고, B를 batch 크기라고 할 때, batch_first = True라고 하면 B * T 크기의 텐서가 반환되고, batch_first = False 이면 T * B shape의 텐서가 반환됩니다.


 

🙋‍♀️피어세션

 

0. TMI 시간 - 매일 돌아가면서 TMI를 말하다보니, 정말 말할게 없어서 오늘 먹었던 밥에 대해 얘기했다. 은근 무슨 얘기를 해야할지 고민이 된다. 

1. 강의 질문 - __getItem__에서 끝 값이 설정되지 않았는데 어떻게 self.num 값만큼만 반복을 하는지 궁금했는데, __len__의 특성 때문이라는 답변을 얻었다. 클래스의 __init__, __len__, __getItem__ 이 세가지를 기본으로, 많이 쓰이는 함수 특성에 대해 공부해야겠다.

2. 코딩테스트 - 프로그래머스에 올라온 위클리 챌린지 중 3주차 문제를 풀어보려고 했는데, 30분 안에 해결 할 수 없는 문제 같았다. 문제를 이해하고, 인사이트를 얻고 시간이 끝나서 다음에 이어서 풀기로 했다.


💌 데일리 회고

 

원래는 강의를 들으면서 강의정리를 했는데, 그 방법이 더 비효율적인 것을 깨닫게 되었다. 나에게 맞는 방식은 우선 강의를 빠르게 본 다음에 헷갈렸던 부분에 대해 고민해본 다음에 다시 강의를 보며 정리를 하는게 더 잘 맞았다. 

댓글