빅데이터 분석 (6주차) 10월14일
미니배치
- GPU가 빠른 이유 core 수가 많기 때문!
- ref: https://ang-love-chang.tistory.com/33
- GPU도 GPU 메모리를 초과할 경우 에러가 뜨면서 실행되지 않을걸?
X_gpu=X.to("cuda:0") y_gpu=y.to("cuda:0") # 전 시간의 이 방법은 X, y를 모두 GPU에 올리는 gpu 메모리를 차지했던 비효율적인 방법이었음
- 방법 1. 가지고 있는 데이터 중 일부만 뽑아 모형을 만들어 STEP을 밟아 나가는 과정
net.to("cuda:0")
- $\hat{y}=f(X*\hat{w})$
- ${n*1}=f({(n*p)}*{(p*1)})$
- p는 조정할 수 없지만 n은 조정할 수 있겠다는 생각.$\to$ 일부를 뽑아볼까
for epoc in range(200): ## 1 yhat_gpu=net(X_gpu) # X_gpu를 나누고 ## 2 loss= loss_fn(yhat_gpu,y_gpu) # 위 나눈 결과가 yhat_GPU에 들어가 loss가 계산됨 ## 3 loss.backward() # 그대로 미분되겠지 ## 4 optimizer.step() net.zero_grad() #모든 일부 뽑은 것들이 계산될 걸!
- Pytorch 로 이 방법 써보기가 이번 수업내용!
import torch
from fastai.vision.all import *
X=torch.tensor([3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
y=torch.tensor([1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0])
X,y
?torch.utils.data.TensorDataset
ds=torch.utils.data.TensorDataset(X,y)
- torch.utils _ ref : https://pytorch.org/docs/stable/data.html
ds ## 그냥 텐서들의 pair , tensor를 pair로 연결한 것이다?!
dir(ds)
ds.tensors # 숨겨져 있던 것들
-
batch_size=2,shuffle=True
dl=torch.utils.data.DataLoader(ds,batch_size=2,shuffle=True) # batch_size데이터를 몇 개로 나눌 건지, shuffle 데이터를 섞을 건지
dl
dir(dl)
- dl은 배치를 만드는 기능이 있어보임
- 저번주에 한 12396개의 데이터를 예로 들어보면 batch 1,2,3,....으로 12396개의 데이터를 나눌 것!
- dl은 ds로 만든 데이터라 xy가 들어있는 모습 dl.dataset.ds에!
for xx,yy in dl:
print(xx,yy)
- xx는 X에서 랜덤으로 2개가 뽑힌 것 (batch_size를 2로 정했으니까)
- yy는 y에서 랜덤으로 2개가 뽑힌 것 (batch_size를 2로 정했으니까)
- 안 남을 때까지! 그래서 마지막은 batch_size 만족하지 못할 수도, 문제가 되는 사안은
- 실핼할 때마다 데이터가 바뀌는 모습 $\to$ suffle =true
-
batch_size=2,shuffle=False
dl=torch.utils.data.DataLoader(ds,batch_size=2,shuffle=False)
for xx,yy in dl:
print(xx,yy)
- 데이터가 바뀌지 않음 $\to$ suffle=false
-
batch_size=3,shuffle=True
dl=torch.utils.data.DataLoader(ds,batch_size=3,shuffle=True)
for xx,yy in dl:
print(xx,yy)
- 3개씩 뽑히는 모습
-
우선 텐서로 이루어진 X,y를 만들자.
path = untar_data(URLs.MNIST_SAMPLE)
threes=(path/'train'/'3').ls()
sevens=(path/'train'/'7').ls()
seven_tensor = torch.stack([tensor(Image.open(i)) for i in sevens]).float()/255
three_tensor = torch.stack([tensor(Image.open(i)) for i in threes]).float()/255
seven_tensor.shape, three_tensor.shape
X=torch.vstack([seven_tensor,three_tensor]).reshape(12396,-1)
y=torch.tensor([0.0]*6265 + [1.0]*6131).reshape(12396,1)
X.shape
-
dataset=(X,y) 를 만들자.
ds=torch.utils.data.TensorDataset(X,y)
ds.tensors
-
dataloader를 만들자.
dl=torch.utils.data.DataLoader(ds,batch_size=2048,shuffle=True) # defalut는 TRUE
dl.dataset.tensors
-
네트워크(아키텍처), 손실함수, 옵티마이저
torch.manual_seed(1)
net = torch.nn.Sequential(
torch.nn.Linear(in_features=784,out_features=30),
torch.nn.ReLU(),
torch.nn.Linear(in_features=30,out_features=1)
#torch.nn.Sigmoid()
)
loss_fn=torch.nn.BCEWithLogitsLoss()
optimizer=torch.optim.Adam(net.parameters())
-
저번시간 복습
for epoc in range(200):
## 1
yhat=net(X)
## 2
loss= loss_fn(yhat,y)
## 3
loss.backward()
## 4
optimizer.step()
net.zero_grad()
plt.plot(yhat.data,'.')
f=torch.nn.Sigmoid() # sigmoid 취한 게 아니니까 취해주자
plt.plot(f(yhat.data),'.')
-
미니배치활용
torch.manual_seed(1)
net = torch.nn.Sequential(
torch.nn.Linear(in_features=784,out_features=30),
torch.nn.ReLU(),
torch.nn.Linear(in_features=30,out_features=1)
#torch.nn.Sigmoid()
)
loss_fn=torch.nn.BCEWithLogitsLoss()
optimizer=torch.optim.Adam(net.parameters())
- 네트워크 파라메터 다시 초기화
12396 / 2048
- 총 7개의 미니배치가 만들어질것임 $\to$ 따라서 파라메터를 업데이트하는 횟수는 7 $\times$ epoc 임 (실제적으로는 6 $\times$ epoc)
200/6 # 6번 epoc 돌렸을때 원해는 값, 즉 33번 정도만 돌리면 되겠네?
for epoc in range(33):
for xx,yy in dl: ### 총 7번돌면 끝나는 for
## 1
yyhat=net(xx)
## 2
loss= loss_fn(yyhat,yy)
## 3
loss.backward()
## 4
optimizer.step()
net.zero_grad()
plt.plot(yyhat.data,'.')
- 이게 왜이러지??
-
배치사이즈를 다시 확인해보자.
for xx,yy in dl:
print(xx.shape,yy.shape)
-
마지막이 108개이므로 108개의 y만 그려짐
list(net.parameters())
plt.plot(net(X).data,'.')
-
2048개 정도만 대충학습해도 동일 반복횟수에 대하여 거의 대등한 효율이 나옴
-
GPU에 있는 메모리로 12396개의 데이터를 모두 보내지 않아도 괜찮겠다 $\to$ 그래픽카드의 메모리를 얼마나 큰 것으로 살지는 자료의 크기와는 상관없다.
-
net.parameters()에 저장된 값들은 그대로 GPU로 가야만한다. $\to$ 그래픽카드의 메모리를 얼마나 큰것으로 살지는 모형의 복잡도와 관련이 있다.
컴퓨터사는방법
- 메모리: $n$이 큰 자료를 다룰수록 메모리가 커야한다.
- GPU의 메모리: 모형의 복잡도가 커질수록 GPU의 메모리가 커야한다.
ds=torch.utils.data.TensorDataset(X,y)
dl=torch.utils.data.DataLoader(ds,batch_size=1024,shuffle=True) # defalut는 TRUE
torch.manual_seed(1)
net = torch.nn.Sequential(
torch.nn.Linear(in_features=784,out_features=30),
torch.nn.ReLU(),
torch.nn.Linear(in_features=30,out_features=1)
#torch.nn.Sigmoid()
)
loss_fn=torch.nn.BCEWithLogitsLoss()
optimizer=torch.optim.Adam(net.parameters())
- 네트워크 파라메터 다시 초기화
12396 / 1024
200*12
- 총 12개의 미니배치가 만들어질것임 $\to$ 따라서 파라메터를 업데이트하는 횟수는 12 $\times$ epoc 임 (실제적으로는 11 $\times$ epoc)
200/11
for epoc in range(18):
for xx,yy in dl:
## 1
yyhat=net(xx)
## 2
loss= loss_fn(yyhat,yy)
## 3
loss.backward()
## 4
optimizer.step()
net.zero_grad()
plt.plot(yyhat.data,'.')
-
배치사이즈를 다시 확인해보자.
for xx,yy in dl:
print(xx.shape,yy.shape)
-
마지막이 108개이므로 108개의 y만 그려짐
list(net.parameters())
plt.plot(net(X).data,'.')