GPU
์์ ํ
์
์กฐ์ ๋ฐ ๋์ ์ ๊ฒฝ๋ง
๊ตฌ์ถ์ด ๊ฐ๋ฅํ ํ๋ ์์ํฌ
โถ๏ธ GPU : ์ฐ์ฐ ์๋๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ ์ญํ
โถ๏ธ ํ ์(tensor)
import torch
torch.tensor([[1., -1.],[1., -1.]])
#----------------------------------#
# ์ถ๋ ฅ๊ฐ
tensor([[1., -1.],
[1., -1.]])
โถ๏ธ ๋์ ์ ๊ฒฝ๋ง: ํ๋ จ์ ๋ฐ๋ณตํ ๋๋ง๋ค ๋คํธ์ํฌ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ ์ ๊ฒฝ๋ง์ ์๋ฏธ
์ฌ์ฉ์๊ฐ ์ดํดํ๊ธฐ ์ฌ์ด API๋ฅผ ์ ๊ณตํ์ฌ ํ ์์ ๋ํ ์ฒ๋ฆฌ์ ์ ๊ฒฝ๋ง์ ๊ตฌ์ถํ๊ณ ํ๋ จํ ์ ์๋๋ก ๋๋๋ค.
Autograd C++, Aten C++, JIT C++, Python API๋ก ๊ตฌ์ฑ๋์ด์๋ค.
๊ฐ์ฅ ์๋ ๊ณ์ธต์ ์ํ๋ C ๋๋ CUDA ํจํค์ง
๋ ์์์ API์์ ํ ๋น๋ ๊ฑฐ์ ๋ชจ๋ ๊ณ์ฐ์ ์ํํ๋ค.
โถ๏ธ ํ ์ ์์ฑ
import torch
print(torch.tensor([[1,2],[3,4]])) # 2์ฐจ์ ํํ์ ํ
์ ์์ฑ
print(torch.tensor([[1,2],[3,4]], device="cuda:0")) # GPU์ ํ
์ ์์ฑ
print(torch.tensor([[1,2],[3,4]], dtype=torch.float64))
# ์ถ๋ ฅ
tensor([[1, 2],
[3, 4]])
------------------------
tensor([[1, 2],
[3, 4]], device='cuda:0')
------------------------
tensor([[1., 2.],
[3., 4.]], dtype=torch.float64)
โถ๏ธ ํ ์ ndarray๋ก ๋ณํ
temp = torch.tensor([[1,2],[3,4]])
print(temp.numpy())
temp = torch.tensor([[1,2],[3,4]], device="cuda:0")
print(temp.to("cpu").numpy()) # GPU์์ ํ
์๋ฅผ CPU์ ํ
์๋ก ๋ณํ ํ ndarray๋ก ๋ณํ
# ์ถ๋ ฅ
[[1 2]
[3 4]]
------------------------
[[1 2]
[3 4]]
โถ๏ธ ํ ์์ ์๋ฃํ
โถ๏ธ ์ธ๋ฑ์ฑ
temp = torch.FloatTensor([1, 2, 3, 4, 5, 6, 7])
print(temp[0], temp[1], temp[-1]) # ์ธ๋ฑ์ค๋ก ์ ๊ทผ
print(temp[2:5], temp[4:-1]) # ์ฌ๋ผ์ด์ค๋ก ์ ๊ทผ
# ์ถ๋ ฅ
tensor(1.) tensor(2.) tensor(7.)
tensor([3., 4., 5.]) tensor([5., 6.])
โถ๏ธ ์ฐ์ฐ
๋ํ์ด์ ndarray์ฒ๋ผ ๋ค์ํ ์ํ ์ฐ์ฐ์ด ๊ฐ๋ฅํ๋ฉฐ, ํ
์ ๊ฐ์ ํ์
์ด ๊ฐ์ ๋ ์ฐ์ฐ์ด ๊ฐ๋ฅํ๋ค.
โถ๏ธ ์ฐจ์
temp = torch.tensor([
[1, 2], [3, 4]
])
print(temp.shape)
print('------------------------')
print(temp.view(4,1))
print('------------------------')
print(temp.view(-1)) # 1์ฐจ์ ๋ฒกํฐ๋ก ๋ณํ
print('------------------------')
print(temp.view(1, -1)) # (1,?)๊ณผ ๊ฐ์ ์๋ฏธ๋ก ๋ค๋ฅธ ์ฐจ์์ผ๋ก๋ถํฐ ํด๋น ๊ฐ์ ์ ์ถํ๊ฒ ๋ค๋ ์๋ฏธ
print('------------------------')
print(temp.view(-1, 1)) # (?,1)๊ณผ ๊ฐ์ ์๋ฏธ๋ก ๋ค๋ฅธ ์ฐจ์์ผ๋ก๋ถํฐ ํด๋น ๊ฐ์ ์ ์ถํ๊ฒ ๋ค๋ ์๋ฏธ
# ์ถ๋ ฅ
torch.Size([2, 2])
------------------------
tensor([[1],
[2],
[3],
[4]])
------------------------
tensor([1, 2, 3, 4])
------------------------
tensor([[1, 2, 3, 4]])
------------------------
tensor([[1],
[2],
[3],
[4]])
๋ฐ์ดํฐ๊ฐ ์ด๋ฏธ์ง์ผ ๊ฒฝ์ฐ ๋ถ์ฐ๋ ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ ์ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ๋ฐฐ์น ๋จ์๋ก ๋ถํ
ํ์ฌ ์ฒ๋ฆฌํ๋ค.
๋ฐ์ดํฐ๊ฐ ํ
์คํธ์ธ ๊ฒฝ์ฐ ์๋ฒ ๋ฉ ๊ณผ์
์ ๊ฑฐ์ณ ์๋ก ๋ค๋ฅธ ๊ธธ์ด์ ์ํ์ค๋ฅผ ๋ฐฐ์น ๋จ์๋ก ๋ถํ ํ์ฌ ์ฒ๋ฆฌํ๋ค.
๐๐ป ์๋ฒ ๋ฉ์ด๋ ์ฌ๋์ด ์ฐ๋ ์์ฐ์ด๋ฅผ ๊ธฐ๊ณ๊ฐ ์ดํดํ ์ ์๋๋ก ์ซ์ํํ์ธ vector๋ก ๋ฐ๊พธ๋ ๊ณผ์ ํน์ ์ผ๋ จ์ ์ ์ฒด ๊ณผ์ ์ ๋ปํ๋ค.
import pandas as pd
import torch
data = pd.read_csv('ํ์ผ ์ด๋ฆ.csv')
x = torch.from_numpy(data['x'].values).unsqueeze(dim=1).float()
y = torch.from_numpy(data['y'].values).unsqueeze(dim=1).float()
๐๐ป squeeze ํจ์๋ ์ฐจ์์ด 1์ธ ์ฐจ์์ ์ ๊ฑฐํด์ค๋ค. ๋ฐ๋ก ์ฐจ์์ ์ค์ ํ์ง ์๋๋ค๋ฉด 1์ธ ์ฐจ์์ ๋ชจ๋ ์ ๊ฑฐํ๋ค. ๋ง์ฝ ์ฐจ์์ ์ค์ ํ๋ค๋ฉด ๊ทธ ์ฐจ์๋ง ์ ๊ฑฐํ๋ค.
๐๐ป unsqueeze ํจ์๋ 1์ธ ์ฐจ์์ ์์ฑํ๋ ํจ์์ด๋ค. ๋๋ฌธ์ ์ด๋ ์ฐจ์์ 1์ธ ์ฐจ์์ ์์ฑํ ์ง ๊ผญ ์ง์ ํด์ฃผ์ด์ผํ๋ค.
(๐ ์ถ์ฒ : https://sanghyu.tistory.com/86)
๊ธฐ๋ณธํํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
class CustomDataset(torch.utils.data.Dataset):
def __init__(self): # ํ์ํ ๋ณ์๋ฅผ ์ ์ธํ๊ณ , ๋ฐ์ดํฐ์
์ ์ ์ฒ๋ฆฌ๋ฅผ ํด ์ฃผ๋ ํจ์
def __len__(self): # ๋ฐ์ดํฐ์
์ ๊ธธ์ด. ์ฆ, ์ด ์ํ์ ์๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์
def __getitem__(self,index): # ๋ฐ์ดํฐ์
์์ ํน์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์(index๋ฒ์งธ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ ํจ์์ด๋ฉฐ, ์ด๋ ๋ฐํ๋๋ ๊ฐ์ ํ
์์ ํํ๋ฅผ ์ทจํด์ผ ํ๋ค.)
tensor_dataset = CustomDataset('ํ์ผ๋ช
')
dataset = DataLoader(tensor_dataset,batch_size=4,shuffle=True)
โถ๏ธ DataLoader
๋ฐ์ดํฐ์ ์ ํน์ง์ ๊ฐ์ ธ์ค๊ณ ํ๋์ ์ํ์ label์ ์ง์ ํ๋ ์ผ์ ํ ๋ฒ์ ํ๋ค.
Dataset์ batch๊ธฐ๋ฐ์ ๋ฅ๋ฌ๋๋ชจ๋ธ ํ์ต์ ์ํด์ ๋ฏธ๋๋ฐฐ์น ํํ๋ก ๋ง๋ค์ด์ ์ฐ๋ฆฌ๊ฐ ์ค์ ๋ก ํ์ตํ ๋ ์ด์ฉํ ์ ์๊ฒ ํํ๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๊ธฐ๋ฅ์ ํ๋ค.
batch
Dataset์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ batch size๋ก slice๋์ด ๊ณต๊ธ๋๋ค.(์ฌ๋ฌ ์ต์ (๋ฐ์ดํฐ ๋ฌถ๊ธฐ, ์ฐ๊ธฐ, ์์์ ๋ณ๋ ฌ์ฒ๋ฆฌ)์ ํตํด batch๋ฅผ ๋ง๋ค์ด ์ค) / ๊ฐ mini-batch์ ํฌ๊ธฐ ์ฆ ํ ๋ฒ์ ๋ฐฐ์น ์์ ์๋ ์ํ ์ฌ์ด์ฆ๋ฅผ ๋งํ๋ค.shuffle
epoch๋ง๋ค ๋ฐ์ดํฐ์ ์ ์์ด, ๋ฐ์ดํฐ๊ฐ ํ์ต๋๋ ์์๋ฅผ ๋ฐ๊พธ๋ ๊ธฐ๋ฅ์ผ๋ก ํ์ต ํ ๋๋ ํญ์ True๋ก ์ค์ ํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.num_worker
๋์์ ์ฒ๋ฆฌํ๋ ํ๋ก์ธ์์ ์๋ก num_worker ํ๋๋ฅผ ๋ ์ถ๊ฐํ๋ฉด 20% ์ ๋ ์๋๊ฐ ๋นจ๋ผ์ง๋ค.
model = nn.Linear(in_features = 1,out_features = 1, bias=True)
โถ๏ธ init() : ๋ชจ๋ธ์์ ์ฌ์ฉ๋ ๋ชจ๋, ํ์ฑํ ํจ์ ๋ฑ์ ์ ์
โถ๏ธ forward() : ๋ชจ๋ธ์์ ์คํ๋์ด์ผ ํ๋ ์ฐ์ฐ์ ์ ์
class MLP(Module):
def __init__(self,inputs):
super(MLP,self).__init__()
self.layer = Linear(inputs,1) # ๊ณ์ธต ์ ์
self.activation = Sigmoid() # ํ์ฑํ ํจ์ ์ ์
def forward(self,x):
X = self.layer(x)
X = self.activation(X)
return X
import torch.nn as nn
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
nn.Sequential์ ๋ชจ๋ธ์ ๊ณ์ธต์ด ๋ณต์กํ ์๋ก ํจ๊ณผ๊ฐ ๋ ๋ฐ์ด๋๋ค!
(๐ ์ถ์ฒ : https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html )
ํ์ตํ๋ ๋์ ์ถ๋ ฅ๊ณผ ์ค์ ๊ฐ ์ฌ์ด์ ์ค์ฐจ๋ฅผ ์ธก์
๋ฐ์ดํฐ์ ์์ค ํจ์๋ฅผ ๋ฐํ์ผ๋ก ๋ชจ๋ธ์ ์ ๋ฐ์ดํธ ๋ฐฉ๋ฒ์ ๊ฒฐ์
โถ๏ธ ์ตํฐ๋ง์ด์ ์ ์ฃผ์ ํน์ฑ
ํ๋ จ๊ณผ ํ ์คํธ ๋จ๊ณ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ค.
โถ๏ธ ์ ์ฐจ
for epoch in range(100):
yhat = model(X_train)
loss = criterion(yhat,y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
์ฃผ์ด์ง ํ ์คํธ ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ํ๊ฐํ๋ค.
model.eval()
๋ชจ๋ธ์ ํ๊ฐํ ๋๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ์ฌ์ฉํ๊ฒ ๋ค๋ ์๋ฐ๋ก ๊ฒ์ฆ๊ณผ ํ ์คํธ ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ๋ค.
๐จ model.eval()์์๋ no_grad()๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค! ๊ฒ์ฆ๊ณผ์ ์์๋ ์ญ์ ํ๊ฐ ํ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.