Open In Colab

파이토치 프로젝트 템플릿

from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive

구글 드라이브 내 파일을 불러옵니다.

!git clone https://github.com/victoresque/pytorch-template
Cloning into 'pytorch-template'...
remote: Enumerating objects: 1516, done.
remote: Total 1516 (delta 0), reused 0 (delta 0), pack-reused 1516
Receiving objects: 100% (1516/1516), 288.08 KiB | 1.03 MiB/s, done.
Resolving deltas: 100% (848/848), done.

깃허브 저장소를 clone(복제) 할 때 사용하는 코드 입니다.

하나의 DL 프로젝트 템플릿인 저장소의 구조는 대략 이렇습니다.

깃허브

저장소를 확인해보시면 단순 노트북 구조가 아닌 하나의 프로젝트를 담고있다는게 체감 될겁니다.

실행, 데이터, 모델, 설정, 로깅, 지표, 유틸리티 등 다양한 모듈을 분리하여 프로젝트를 템플릿화 했습니다.

레고블럭도 쌓으면 하나의 작품이 되듯 DL코드도 단순한 노트북 공유가 아닌 하나의 프로그램을 만든다고 생각하는 것이 좋습니다.

이번주 내로 여기있는 코드를 주석을 달며 리뷰하면서 구조가 어떻게 되는지 이해해보겠습니다.

config 파일을 바꾸면 손쉽게 전체 구조가 바뀌고 모델학습 정도가 파일 내 지속적으로 로깅되는 등 상당히 체계적이라고 생각했어요.

딥러닝 프로젝트를 협업할 때 시간을 단축시킬 도구라고 생각합니다.

통계학과 출신이라 이런 분야에 많이 부족한데 정말 질 좋은 강의 듣고 혼자 공부 열심히 해보겠습니다.

!ls
drive  pytorch-template  sample_data
%cd /content/pytorch-template
/content/pytorch-template

터미널 환경 명령어를 사용해 clone을 한 폴더로 이동했습니다.

!python new_project.py MNIST-example
New project initialized at /content/pytorch-template/MNIST-example

new_project.py 파일을 MNIST-example 옵션을 주어 실행합니다.

코렙을 VSCode 환경에서 실행하기

1) 우선 다음사이트 ( https://ngrok.com/ )에 접속하여 회원가입을 합니다.

2) 개인에게 할당된 토큰을 복사합니다.

image

3) 코렙에서 다음 코드를 모두 실행시킵니다.

NGROK_TOKEN = '2FHrt2P3Xe1ZY0HVM5pwxgds3Tx' # 받아온 토큰을 여기에 넣습니다.
PASSWORD = 'upstage'
!pip install colab-ssh
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting colab-ssh
  Downloading colab_ssh-0.3.27-py3-none-any.whl (26 kB)
Installing collected packages: colab-ssh
Successfully installed colab-ssh-0.3.27
from colab_ssh import launch_ssh
launch_ssh(NGROK_TOKEN, PASSWORD) # 이 코드의 결과값

실행결과

4) HostName 내 다음 확장 파일을 설치합니다.

remote

5) ctrl + shift + p 를 누르시고 remote ssh add 를 입력할 때 나오는 것을 클릭합니다. 밑 그림이 나오면 성공입니다.

remote2

6) 입력칸에 ssh root@(윗 코드 결과에 HostName 값) -p (윗 코드 결과에 Port 값) 을 입력합니다. 이후 엔터를 연이어 누릅니다.

7) ctrl + shift + p 를 누르시고 remote ssh connect to host 를 입력할 때 나오는 것을 클릭합니다. 이후 엔터를 연이어 누릅니다. 아래 그림 뒤에 새 vscode가 실행되면 성공입니다.

remote3

8) 운영체제 상관없이 리눅스 클릭하고 엔터 누르고 앞서 코렙에서 설정한 비밀번호 입력하면 연결이 완료됩니다!

VScode로 파이토치 프로젝트 템플릿 사용해보기

colab1

코렙 환경에 잘 접속했다는 것을 VSCode에서 확인할 수 있습니다.

colab2

이런 식으로 코렙 내 파이썬 파일을 실행할 수 있습니다.

colab3

실제 구글 드라이브가 있는 폴더에 접근해 파일을 만질 수 있습니다. 이 코드에 경우 워크스페이스에 있는 파일을 구글 드라이브에 복사했습니다.

텐서플로우와 파이토치

텐서플로우는 Production에 유리하며 cloud 환경에도 사용이 용이하며 멀티GPU와 호환이 좋습니다.

반면 파이토치는 논문작성이나 단순구현시 텐서플로우보다 더 좋습니다. 공부하기에 좋은 라이브러리 입니다.

파이토치를 크게 나누면 '넘파이 + 자동미분 + 함수'로 생각할 수 있습니다. 넘파이와 유사한 사용법을 가지며 자동미분이 가능하고 여러가지 함수도 내장하고 있습니다.

위 내용을 다음 장에서 살펴보겠습니다.

Pytorch 기초

넘파이엔 ndarray를 사용하듯이 파이토치는 Torch를 사용합니다.

ndarray와 Torch는 거의 유사합니다. 즉 넘파이의 대부분의 사용법이 파이토치에 적용됩니다.

device

import torch
data = [[3, 5, 20],[10, 5, 50], [1, 5, 10]]
x_data = torch.tensor(data)
x_data.device
device(type='cpu')
if torch.cuda.is_available(): # gpu 사용 가능하다면 (cuda : 코렙 gpu)
    x_data_cuda = x_data.to('cuda') # 텐서 데이터를 gpu에 실음
x_data_cuda.device
device(type='cuda', index=0)

파이토치의 텐서는 GPU에 올려서 사용 가능합니다.

view와 reshape

tensor_ex = torch.rand(size=(2, 3, 2))
tensor_ex.reshape([-1,6])
tensor([[0.6184, 0.5495, 0.1053, 0.9560, 0.4484, 0.8413],
        [0.1381, 0.5541, 0.2258, 0.5828, 0.9683, 0.7885]])
tensor_ex.view([-1, 6])
tensor([[0.6184, 0.5495, 0.1053, 0.9560, 0.4484, 0.8413],
        [0.1381, 0.5541, 0.2258, 0.5828, 0.9683, 0.7885]])
a = torch.zeros(3, 2)
b = a.view(2, 3)
a.fill_(1)
b # copy가 안 일어났음을 알 수 있음
tensor([[1., 1., 1.],
        [1., 1., 1.]])

파이토치 내 view 함수는 reshape 함수와 거의 유사합니다. 다만 view와 달리 reshape는 카피가 일어납니다. 주로 view를 사용합니다.

squeeze와 unsqueeze

tensor_ex = torch.rand(size=(2, 1, 2))
print(tensor_ex.shape)
tensor_ex
torch.Size([2, 1, 2])
tensor([[[0.3405, 0.0974]],

        [[0.8834, 0.3748]]])
tensor_ex.squeeze()
tensor([[0.6641, 0.1000],
        [0.4968, 0.1627]])

squeeze 함수는 의미없는 리스트 씌움을 없애줍니다.

tensor_ex = torch.rand(size=(2, 2))
print(tensor_ex.unsqueeze(0).shape)
print(tensor_ex.unsqueeze(1).shape)
print(tensor_ex.unsqueeze(2).shape)
torch.Size([1, 2, 2])
torch.Size([2, 1, 2])
torch.Size([2, 2, 1])

unsqueeze

unsqueeze 함수는 리스트를 한번 씌워줍니다.

operation

import numpy as np
n1 = np.arange(10).reshape(2,5) # (2 * 5) 행렬
n2 = np.arange(10).reshape(5,2) # (5 * 2) 행렬
t1 = torch.FloatTensor(n1)
t2 = torch.FloatTensor(n2)

# t1.dot(t2), 오류. dot는 넘파이와 달리 1차원 벡터 연산만 가능 
t1.mm(t2) # 행렬곱 연산
tensor([[ 60.,  70.],
        [160., 195.]])

mm 함수를 사용해 행렬 곱 연산이 가능합니다.

a = torch.rand(5, 2, 3)
b = torch.rand(3)
a[0].mm(torch.unsqueeze(b,1)).squeeze() # torch.unsqueeze(b,1) => (3, 1) 행렬, a[0] => (2, 3) 행렬
tensor([1.4147, 0.8625])

nn.functional

import torch
import torch.nn.functional as F # 다양한 내장 함수가 존재함.

tensor = torch.FloatTensor([0.5, 0.7, 0.1])
h_tensor = F.softmax(tensor, dim=0)
h_tensor
tensor([0.3458, 0.4224, 0.2318])
y = torch.randint(5, (10,5))
y_label = y.argmax(dim=1)
print(y_label)
torch.nn.functional.one_hot(y_label) # 원-핫 인코딩 함수도 존재함.
tensor([1, 1, 3, 0, 4, 2, 1, 0, 4, 0])
tensor([[0, 1, 0, 0, 0],
        [0, 1, 0, 0, 0],
        [0, 0, 0, 1, 0],
        [1, 0, 0, 0, 0],
        [0, 0, 0, 0, 1],
        [0, 0, 1, 0, 0],
        [0, 1, 0, 0, 0],
        [1, 0, 0, 0, 0],
        [0, 0, 0, 0, 1],
        [1, 0, 0, 0, 0]])

backward 자동미분

a = torch.tensor([2., 3.], requires_grad=True) # requires_grad을 True로 해주어야 자동 미분이 가능함.
b = torch.tensor([6., 4.], requires_grad=True) # 딥러닝 모델에선 linear 함수에 이미 적용했기 때문에 신경 쓸 부분은 적음.
Q = 3*a**3 - b**2
external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)

print(a.grad)
print(b.grad)
tensor([36., 81.])
tensor([-12.,  -8.])

느낀점

항상 느끼는게 강의가 배울 것이 많아 좋은 것 같습니다.

부스트 캠프를 하기로 마음 먹은 이유 중 하나가 통계학과 출신이라 코렙을 활용한 코드 작성은 어느정도 괜찮지만 오늘 배운 내용과 같이 프로젝트 형식으로 협업을 하거나 환경을 구축하는 것에 있어 많이 약점이라 스스로 생각하는데 이 부분을 매꿀 수 있어서 좋은 것 같아요.

아직은 강의 듣고 내용 정리까지 했는데 과제(양을 얼핏 보니 두렵네요)를 하고 나면 이 분야에서 많이 성장할 것에 기대됩니다.

쉬고와서 괜찮을 줄 알았는데 역시 월요일은 힘드네요. 더 화이팅 해야겠습니다.

** 위 수식과 그림은 부스트캠프 AI Tech 교육 자료를 참고하였습니다.