정리노트
Deep Learning (3)_ Pytorch 본문
앞선 포스팅에서 간단한 Neural Network구조인 MLP를 다루었는데,
그 단순한 모델인데도 각 Activation의 Gradient부터 일일이 가중치를 Update하는 일까지 꽤 복잡한 과정을 거친 것을 확인할 수 있었다. 그렇다면 모든 딥러닝을 구현할때 이런과정을 거쳐야할까?
아니다.
파이썬에는 Pytorch, Tensorflow, Keras같은
Deep Neural Network를 구현하는 훌륭한 오픈소스 Framework가 있고, 실제 모델을 구현하는 단계에서는 이런 Framework를 잘 구성해주면 복잡한 과정을 거치지 않아도 비교적 단순하게 모델을 구현할 수 있다.
이번 포스팅에서는 바로 이 pytorch Deep Learning Framework에대해서 자세히 다뤄보도록 하겠다.
.
◆목차
◎ With & Without Pytorch (Shallow Neural Network)
◎ torch.Tensor
○ Torch Data Type
○ Tensor Operation
◎ Autograd
○ with torch.no_grad():
○ Avoiding in-Place Operation in Autograd
◎ nn.Module
◎ With & Without Pytorch (Shallow Neural Network)
같은 Shallow Neural Network를
하나는 Numpy,
다른 하나는 Pytorch 패키지로 구현해보면서
Pytorch 프레임워크의 일반적인 구조를 살펴보도록 하자.
보통 크게, 인공지능을 구현할때
1, Data Preprocessing(전처리)
2, Data Pipelining
3, Modeling
4, Training
정도의 단계를 거치는데, 지금 이야기 하려는 단계는 Modeling, Training이다.
먼저 아래와같이 Neural Network 모델을 구현해보자.
왼쪽은 Pytorch없이 Numpy로만 구현한 모델이고,
오른쪽은 Pytorch로 구현한 모델이다.
Numpy로 구현한 모델에서는
training 코드에서 Back Propagation의 Gradient값을 일일이 구현해 주어야 하므로
Foward Pass에서 Return 값으로
첫번째 레이어의 Output값 a1,
두번째 최종레이어의 Output값 a2 값까지
모조리 반환해야 training코드를 짤 수 있다.
그러나 Pytorch에서는
parameter을 tracking하여 자동으로 Gradient값을 찾아주는 Auto Gradient 기능 덕분에
Gradient값을 일일이 구현할 필요없어지고,
Forward Pass에서도 최종 결과값인 a2만 반환해주면 된다.
Pytorch로 모델을짤때는 nn.Module이라는 클래스를 상속하여 사용하는데,
https://pytorch.org/docs/stable/nn.html
nn.Module안에 Deeplearning을 구축하는데 필요한 Submodule이 다 들어 있어서,
원할때 편하게 꺼내쓰면 되는 구조로 되어있다.
아래는 Numpy로 구축한 모델의 Training 과 Pytorch로 구축한 모델의 Training과정을 비교해 놓은 것이다.
구현한 모델로 Training을 할때,
Numpy로 구현한 모델은 일일이 Gradient값을 구해서 기입해주고, update해줘야하는 반면,
Pytorch로 구현한 모델은 Autograd 기능덕분에 backward() 메서드만 호출해주면 Optimizer에 따라 Gradient 값에따른 Backpropagation을 진행해준다.
같은 트레이닝 과정이지만 pytorch 프레임워크에서 짰을때 가독성이 좋고 속도도 훨씬 빠르다.
Pytorch는 GPU가속을 사용할 수 있도록 디자인 되어있기 때문에, Data Pipelining만 잘해주면 엄청난 속도로 수많은 데이터를 처리할 수 있다.
◎ torch.Tensor
Linear Algebra에서 다루는 Tensor개념처럼, PyTorch텐서역시 여러차원의 Array로 이루어져있으며,
Numpy의 거의 모든 기능이 지원되고, 추가로 GPU Accelearion이 가능하다.
○ Torch Data Type
아래 링크에서 Torch에 쓰이는 Data Type을 확인할 수 있다.
https://pytorch.org/docs/stable/tensors.html
Default Data Type은 32bit floating point이다.
○ Tensor Operation
Tensor의 Operation은 Numpy와 매우 비슷해서, Numpy연산에 익숙한 사람이라면 금방 따라갈 수 있을 것이다.
아래는 torch에서 사용하는 Tensor연산에대해 가볍게 정리해둔 것이니,
혹시라도 모르는게 있다면 한번쯤 참조해보면 좋을 듯 하다.
- Accessing Elements
Torch의 Default Data Type은 32bit floating point라서, 정수를 기입해도 실수형 자료형을 Return하는 것을 볼 수 있다.
항상 Tensor값을 반환하며, tensor가 아니라 그냥 안에들어있는 데이터를 보고싶으면 item()메서드를 사용한다.
- Slicing
Numpy, Pandas 패키지를 써본 사람이라면 익숙한 슬라이싱.
Numpy와 다를게 없다.
indexing Number : 순서
=> 0부터시작 : 1부터시작
- Negative Slicing
음의 인덱싱도 Numpy, Pandas와 똑같다
- Shape & Transpose
- Sum
특정 차원에 있는 모든 Elements를 더하는 Method로,
keepdim 파라미터를 이용해 차원을 유지할지 결정한다.
(유지하지 않는다면 차원이 줄어든다.)
dim에 대한 정의를
2차원 텐서인 경우 0,1 (또는 -1,-2)로 할 수 있으며,
3차원 텐서의 경우 0,1,2까지 할 수 있다.
위 그림에서 예시는 0(열), 1(행)에대한 sum을 진행한 그림으로, keepdim 파라미터로 차원을 유지하는 그림을 확인할 수 있다. -> tensor([6. , 5.]) 이 아니라 tensor([[6.] , [5.]])
- Mean
mean() 메서드도 sum()에서와 비슷한데, 특정차원, 혹은 모든 차원에 대해서 평균을 반환할 수 있다.
0인경우가 열, 1인경우가 행에대한 평균.
3차원 텐서인경우 2까지 사용가능하다.
- Max
0인경우가 열, 1인경우가 행에대한 평균
3차원 텐서인경우 2까지 사용가능하다.
- Bianry Operation
- Inner Product
으레, Torch로 모델을 구현하다보면
차원의 수와 shape를 맞추주려고 아래 그림 처럼 씨름하게되기 마련인데, 이때 쓰기 유용한 Operation으로
view, squeeze/unsqueeze이 있다.
- View
예시를 보면 이해가 쉬울것이다
- Squeeze / Unsqueeze
아래의 broadcasting 수동버전으로 생각해두면 될 듯하다
- Broadcasting
Broadcasting은, Tensor연산과정에서 서로다른 차원개수의 텐서를
차원수를 맞춰주며 연산가능하도록 하는 기능으로,
이에대한 설명은 아래 블로그에 자세히 나와있다
https://mclearninglab.tistory.com/85
Pytorch가 Broadcasting을 지원하려면, 아래조건을 만족해야한다.
각 텐서의 끝자락부터의 순서로
1, 텐서차원이 같거나,
2, 1이거나
3, 차원이 없거나.
위 예시를 보면, (2,3,3)크기의 텐서인 X는,
(1,1,3) , (1,3) , (3) 사이즈의 텐서와의 연산에서 Broadcasting이 가능한 것을 알 수있다.
X 가 (2,3), Y가 (2)인 텐서이고,
이때 X의 마지막 차원인 3과 Y의 마지막 차원인 2가 서로 다르기 때문에 Broadcasting이 지원이 안되는 모습을 볼 수 있다. -> X를 Transpose하여(3,2)로 만들어준다면, 아까전 예시처럼 Broacasting이 가능해진다.
- ndarray, tensor
Numpy의 ndarray와 Pytorch의 Tensor끼리 왔다갔다 하는 메서드이다.
*단, 여기서 만약에 데이터가 Cuda device에 할당되어있다면 작동하지 않을 수도 있다..
이럴경우 할당된 데이터를 다시 해제 시키도록 해야하는데,
아래처럼 진행해주면 된다.
'cuda' Device에 할당되어 있을시 다시 cpu로 detach해주고 numpy로 바꿔주어야 한다.
◎ Autograd
Neural Network의 노드와 레이어 개수가 많아질 수록, 계산해야하는 Gradient는 무한히 많아진다.
글 시작부에서, Pytorch Framework에서는 Gradient를 계산해줄 때, 일일이 기입해주지 않아도 자동으로 Gradient를 계산해주고, 이를 Tracking해준다고 언급하였다.
이 기능을 Pytorch의 'Autograd'기능이라고 한다.
아래 블로그에 Auto_grad내용이 잘 정리되어있으니 참조
https://blog.naver.com/PostView.nhn?blogId=je_un&logNo=222298692213
require_grad=True가 되어있을때, 파라미터 Value를 Tracking할 수 있고,
Backward() 메서드를 입력만해주면 Tracking된 Value를 기반으로 Gradient를 알아서 계산해준다.
자세한 설명은 위 블로그에 잘 정리가 되어있어서, 궁금하다면 한번 꼭 읽어보길 바란다.
○ with torch.no_grad():
https://go-hard.tistory.com/64
Gradient는 Training과정의 Back Propagation을 하기 위해서 필요한 것이기 때문에,
Forward Propagation, 즉, 모델 자체의 Prediction값을 테스트하고 싶을때는 굳이 필요하지 않고 계산 속도만 저해할 뿐인 기능이 된다.
딥러닝 코드들을 보면
이렇게 선언해놓고 그 안에서 코딩이 구현된 경우가 많은데,
require_grad를 False로 바꿔주는 기능이라고 생각하면 된다. (그렇기때문에 with 안에서는 Backward()는 불가능하다)
○ Avoiding in-Place Operation in Autograd
in-place Operation란, tensor의 값을 바꿀 때, 해당 메모리에 값을 Copy하여 바꾸는 것이 아닌, 직접 메모리에 접근하여 값을 바꾸는 Operation을 의미한다.
앞서 Autograd의 핵심은 Parameter Value를 Tracking하여 그 변화량을 알아내는 것이라고 언급하였다.
이 Autograd가 제대로 동작하기 위해서는, in-place Operation을 사용하지 말아야한다. (구체적인 이유는 알수없지만)
아래 예시처럼 inplace Operation가 아닌, 별도의 메모리를 Copy하여 사용하도록 모든 연산을 진행시켜야 Autograd가 제대로 작동된다.
◎ nn.Module
포스팅 앞부분에서도 언급했듯,
pytorch는 모델을 구성할 때, nn.Module를 상속받아 사용한다.
이 내용에 대해서는 아래 블로그에 잘 정리되어있다
https://daebaq27.tistory.com/60
class 클래스이름(nn.Module):
def __init__(self):
super(클래스이름,self).__init__()
를 클래스 선언과 함께 해주는게 국룰인데 이걸 하는 이유까지 위 블로그에 잘 나와있다.
nn.module은 클래스를 Submodule화 하여 Parameter Tracking을 진행하는 것으로 알고있는데 (아마 맞을거임)
super().__init()__을 해주는 이유도, 바로 이 클래스를 modules화 해주기 위해서 초기화 해주는 것이다.
-> Training
nn.Module을 상속받아 구성한 모델을 Training하는 과정은
보통 아래와같은 3단계를 거친다.
1, initialization..
Optimizer를 설정해주고, Learning rate를 결정한다.
2, Forward
Class의 forward() method에 input값을 넣어 Forward Propagation한다
3, Backward
loss를 설정해 준 후,
Autograd의 힘을 빌려서 loss의 Gradient값을 도출한다. 그리고 Optimizer.Step()을 이용해 이를 Propagation시켜준다.
.... 그 복잡한 과정이 3단계로 요약됐다..
'AI > Deep Learning' 카테고리의 다른 글
Deep Learning (6) _Optimization (0) | 2022.04.23 |
---|---|
Deep Learning (5) _ Practical Aspect (0) | 2022.04.22 |
Deep Learning (4)_DNN (Deep Neural Network) (0) | 2022.04.21 |
Deep Learning (2)_ Shallow Neural network (0) | 2022.04.20 |
Deep Learning (1) - Linear Regression, Logistic Regression (0) | 2022.04.20 |