pbj0812의 코딩 일기

[PYTORCH] 04_pytorch with examples (autograd 재정의) 본문

인공지능 & 머신러닝/PYTORCH

[PYTORCH] 04_pytorch with examples (autograd 재정의)

pbj0812 2019. 6. 10. 00:02

Pytorch with examples (autograd 재정의) 코드 분석

- 아래 글은 파이토치 튜토리얼 중 autograd를 재정의 하는 부분을 학습하여 영상으로 만든 것을 재구성한 글입니다.

 

원본링크 : https://pytorch.org/tutorials/beginner/pytorch_with_examples.html

유투브 영상 : https://youtu.be/TclwMS-eZuU

한글 주석 코드https://github.com/pbj0812/deep_learning/blob/master/pytorch_tutorial/learning_pytorch_with_examples_new_func.ipynb

 

코드 프리뷰

코드 프리뷰

기본구조

기본구

- 기존과 동일하다.

함수 재정의

class MyReLU(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input):
        ctx.save_for_backward(input)
        return input.clamp(min=0)
    
    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_tensors
        grad_input = grad_output.clone()
        grad_input[input < 0] = 0
        return grad_input

- 목적 : 결과 값에 ReLU 적용

- MyReLU 라는 새로운 클래스를 생성한다.

- input으로는 pytorch에 내장된 torch.autograd.Function을 사용한다.

- @staticmethod를 사용하여 forward 함수와 backward 함수를 재정의한다.

- backward에서 ReLU 적용 조건으로 [input < 0]을 둔 것은 forward 연산시 ReLU가 적용된 위치를 부르기 위함이다.

Device setting

dtype = torch.float
# device = torch.device("cpu")
device = torch.device("cuda:0")

'''지난시간
dtype = torch.float
# device = torch.device("cpu")
device = torch.device("cuda:0")
'''

- 지난 시간과 동일하다.

Hyper parameter setting

N, D_in, H, D_out = 64, 1000, 100, 10
learning_rate = 1e-6

x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)


''' 지난시간
N, D_in, H, D_out = 64, 1000, 100, 10
learning_rate = 1e-6

x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
'''

하이퍼 파라미터  세팅

- 지난 시간과 동일하다.

h layer 생성부터 y_pred 생성까지

relu = MyReLU.apply
y_pred =relu(x.mm(w1)).mm(w2)

'''지난시간
y_pred = x.mm(w1).clamp(min=0).mm(w2)
'''

 

h layer 생성
ReLU 구현
y_pred 예측

- apply 함수를 사용하여 MyReLU의 기능을 relu에 적용하였다.

- 지난시간에 clamp(min=0)을 사용한 부분이 이번 시간에는 MyReLU에 넣어주었기 때문에 생략되었다.

loss function

loss = (y_pred - y).pow(2).sum()

'''지난시간
loss = (y_pred - y).pow(2).sum()
'''

loss function

- 지난 시간과 동일하다.

loss function 미분 ~ backward

loss.backward()

'''지난시간
loss.backward()
'''

 

- 지난 시간과 동일하다.

- 차이점은 지난 시간에는 backward 연산시 ReLU가 적용되지 않았다는 점이고, 이번 시간에는 class를 새로 선언시 ReLU를 적용하였다는 점이다.

weight 갱신

w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2

'''지난시간
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
'''

- 지난시간과 동일하다.

gradient 초기화

w1.grad.zero_()
w2.grad.zero_()

'''지난시간
w1.grad.zero_()
w2.grad.zero_()
'''

- 지난시간과 동일하다.

속도비교

방법

장치

속도(s)

순위

Numpy

CPU

6.26

2

PyTorch(Tensor)

CPU

6.31

3

PyTorch(Tensor)

GPU

24.37

6

PyTorch(autograd)

CPU

5.62

1

PyTorch(autograd)

GPU

15.58

5

PyTorch(new_func)

CPU

10.21

4

PyTorch(new_func)

GPU

30.28

7

- 이번 시간에 적용한 부분은 아래에서 첫 번째, 두 번째에 해당하는 부분이다.

- 지난 시간에 비해서 두배 가량 시간이 증가한 것을 볼 수 있는데, 이는 ReLU적용의 유무의 차이에서 오는 것으로 보인다.

* backward 연산에서 ReLU 적용 부분을 주석 처리했을때, 속도가 지난번과 비슷하게 나온다.

Comments