시작하기에 앞서 rTorch GPU설정은 아래 링크를 참조하기 바란다.
아래는 R에서 tensorflow GPU로 사용한 같은 데이터 예제이다.
pytorch LSTM예제를 찾다 보니 공교롭게 AirPassengers 자료가 나왔다.
그래서 해당 코드를 R로 복기하는 것으로 rTorch를 포스팅하기로 했다.
아래는 pytorch에서 AirPassengers를 예측하는 코드를 짜신거 같다.
stackabuse.com/time-series-prediction-using-lstm-with-pytorch-in-python/
기존 예제는 GPU세팅이 안되있어서, 어차피 rTorch 관심사일거 같아서 GPU세팅을 추가해보았다.
library(reticulate)
library(torch)
library(rTorch)
torch=rTorch::torch
nn=rTorch::torch$nn
torch$cuda$is_available()
torch$cuda$current_device()
torch$cuda$device_count()
torch$cuda$get_device_name(0L)
torch$cuda$get_device_name(1L)
torch$cuda$device(0)
device = torch$cuda$device(0L)
cuda = torch$device('cuda')
잘 나온다.
자료를 자료의 timestepdms 12로 두었으며, 최대 최소 정규화를 진행하였다.
GPU를 사용하기 위해 to(device=cuda)를 설정하였다.
data(AirPassengers)
all_data=as.vector(AirPassengers)
train_data=all_data[1:(length(all_data)-12)]
test_data=all_data[(length(all_data)-11):length(all_data)]
print(paste(length(train_data),length(test_data)))
tr_max=max(train_data);tr_min=min(train_data)
train_data_normalized=torch$Tensor((train_data-tr_min)/(tr_max-tr_min))$to(device=cuda)
train_window = 12
create_inout_sequences=function(input_data,tw){
inout_seq=list()
L=length(input_data)
for(i in 1:(L-tw-1)){
train_seq=input_data[i:(i+tw)]
train_label=input_data[(i+tw+1)]
inout_seq[[i]]=list(train_seq,train_label)
}
return(inout_seq)
}
train_inout_seq = create_inout_sequences(input_data=train_data_normalized, tw=train_window)
python 클래스 개념을 아래와 같이 가지고 오게 잘 되어있었다.
py_run_string("import torch")
main = py_run_string(
"
import torch.nn as nn
class LSTM(nn.Module):
def __init__(self, input_size=1, hidden_layer_size=100, output_size=1):
super().__init__()
self.hidden_layer_size = hidden_layer_size
self.lstm = nn.LSTM(input_size, hidden_layer_size)
self.linear = nn.Linear(hidden_layer_size, output_size)
self.hidden_cell = (torch.zeros(1,1,self.hidden_layer_size),
torch.zeros(1,1,self.hidden_layer_size))
def forward(self, input_seq):
lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq) ,1, -1), self.hidden_cell)
predictions = self.linear(lstm_out.view(len(input_seq), -1))
return predictions[-1]
")
아래는 LSTM의 학습과정이다.
마찬가지로 GPU사용을 위해 cuda()를 사용하였으며, empth_cache()는 안쓰는 캐시를 지우는 코드에 해당한다.
model=main$LSTM()$cuda()
loss_function = nn$MSELoss()
optimizer = rTorch::torch$optim$Adam(model$parameters(), lr=0.001)
torch$cuda$empty_cache()
epochs = 150
for(i in 1:epochs){
for(j in train_inout_seq){
seq=j[[1]];labels=j[[2]]
optimizer$zero_grad()
model$hidden_cell = c(torch$zeros(list(1L, 1L, model$hidden_layer_size))$cuda(),
torch$zeros(list(1L, 1L, model$hidden_layer_size))$cuda())
y_pred = model(seq)
single_loss = loss_function(y_pred, labels)
single_loss$backward()
optimizer$step()
}
if(i%%25 == 1){
print(paste0('epoch: ',round(i,3),' loss: ',round(single_loss$item(),8)))
}
}
원 저자는 working forward 형식으로 예측을 진행한 것 같다.
fut_pred = 12
test_inputs = train_data_normalized[(length(train_data_normalized)-11):length(train_data_normalized)]$tolist()
test_inputs
model$eval()
for(i in 1:fut_pred){
seq = torch$FloatTensor(test_inputs[(length(test_inputs)-11):length(test_inputs)])$cuda()
with(torch$no_grad(),{
model.hidden = c(torch$zeros(list(1L, 1L, model$hidden_layer_size))$cuda(),
torch$zeros(list(1L, 1L, model$hidden_layer_size))$cuda())
test_inputs=c(test_inputs,model(seq)$item())
})
}
test_inputs[fut_pred:length(test_inputs)]
y=test_inputs[fut_pred:length(test_inputs)]*(tr_max-tr_min)+tr_min
x = 132:144
length(train_data)
plot(1:length(all_data),c(train_data,rep(NA,12)),type='l',ylim=c(100,700))
points(x,y,type='l',col=2)
points(x,all_data[x],type='l',col=3)
'통계 및 인공지능' 카테고리의 다른 글
1D-CNN & Multi input Multi output Model in R (1) | 2021.05.02 |
---|---|
R에서 ELMO 모형 사용하기 (0) | 2021.04.26 |
R tensorflow LSTM 예제 코드(GPU 사용) (0) | 2021.04.24 |
트리모델과 더미화 (0) | 2021.02.28 |
[Boruta] 차원 축소 기법 (0) | 2021.02.28 |