통계 및 인공지능

rTorch LSTM 예제 코드(GPU 사용)

cj92 2021. 4. 24. 20:11

시작하기에 앞서 rTorch GPU설정은 아래 링크를 참조하기 바란다.

 

rcj92.tistory.com/10

 

R tensorflow-gpu 설정하기

오늘은 R쓰시는 분들이 딥러닝 할 때 GPU세팅을 힘들어해서 R에서 tensorflow를 gpu로 돌리기 위한 세팅을 해보겠다. 지금은 tensorflow라이브러리에서 install_tensorflow()를 활용하면 쉽게 가능하다고 하

rcj92.tistory.com

 

아래는 R에서 tensorflow GPU로 사용한 같은 데이터 예제이다. 

 

rcj92.tistory.com/11

 

R tensorflow LSTM 예제 코드

lstm 모형 구축을 하기 앞서 딥러닝 코드 구현도 충분히 중요하지만, 이론을 모르는 상황에서 모델을 개선 시킬 수는 없다고 생각한다. 그런 의미에서 아래 링크를 공유한다. ducj.tistory.com/227 순환

rcj92.tistory.com

pytorch LSTM예제를 찾다 보니  공교롭게 AirPassengers 자료가 나왔다.

 

그래서 해당 코드를 R로 복기하는 것으로 rTorch를 포스팅하기로 했다.

 

아래는 pytorch에서 AirPassengers를 예측하는 코드를 짜신거 같다.

 

 

stackabuse.com/time-series-prediction-using-lstm-with-pytorch-in-python/

 

Time Series Prediction using LSTM with PyTorch in Python

Time series data, as the name suggests is a type of data that changes with time. For instance, the temperature in a 24-hour time period, the price of various products in a month, the stock prices of a particular company in a year. Advanced deep learning mo

stackabuse.com

기존 예제는 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)