통계 및 인공지능

R tensorflow LSTM 예제 코드(GPU 사용)

cj92 2021. 4. 24. 18:15

lstm 모형 구축을 하기 앞서 딥러닝 코드 구현도 충분히 중요하지만,

 

이론을 모르는 상황에서 모델을 개선 시킬 수는 없다고 생각한다.

 

그런 의미에서 아래 링크를 공유한다.

 

ducj.tistory.com/227

 

순환신경망(1/3)

 

ducj.tistory.com

 

아래는 환경을 구축하는 링크다.

 

rcj92.tistory.com/10

 

R tensorflow-gpu 설정하기

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

rcj92.tistory.com

자, 이제 본격적으로 시계열 예측을 시작해보자.

 

아래 자료는 시계열 예측 예제로 많이 사용되는 AirPassengers 자료이다.

 

해당 포스팅은 정확도가 목표가 아니라 예제 코드를 제공하는 것이 목적이므로 성능은 가볍게 넘어 가주길 바란다.

 

 

library(reticulate)
library(forecast)
library(dplyr)
library(tensorflow)
library(keras)
# 자료 구축
data('AirPassengers')
ap_ts <- window(AirPassengers, start=1949, end=1958.99)
ap_ts_test <- window(AirPassengers, start=1959)

 

대충 이러한 자료의 형태를 띈다.

 

학습자료는 timestep이 12인 자료로 구성해 보았다.

 

 

학습자료는 x는 107, 12, 1  y는 107 ,1로 차원을 나타내었다.

data_generate=function(ap_ts){
  tr=as.vector(ap_ts)
  tr_xs=list();tr_ys=list()
  for(i in 1:(length(tr)-13)){
    tr_xs[[i]]=tr[i:(i+11)]
    tr_ys[[i]]=tr[i+12]
  }
  tr_x=t(data.frame(tr_xs))
  tr_y=t(data.frame(tr_ys))
  rownames(tr_x)=NULL
  rownames(tr_y)=NULL
  tr_x=array(tr_x,c(nrow(tr_x),ncol(tr_x),1))
  return(list(tr_x,tr_y))
}
tr_=data_generate(ap_ts)
tr_x=tr_[[1]];tr_y=tr_[[2]]
te_=data_generate(ap_ts_test)
te_x=te_[[1]];te_y=te_[[2]]

dim(tr_x);dim(tr_y)

 

tensorflow에서는 아래와 같은 모형을 크게 input함수랑 sequential함수 두 방식으로 구성할 수 있다.

별다른 차이는 없으나 복잡한 신경망 구조를 생성하기 위해서는 타입2처럼 input함수로 처리하는 것이 좀 더 유연하다고 한다.

 

# 타입 1

model=
  keras_model_sequential()%>%layer_lstm(units=50,input_shape =c(6,1),return_sequences = T)%>%
  layer_lstm(50,return_sequences = T)%>%
  layer_dense(1)
model

 

# 타입 2

input=layer_input(shape=c(6,1))
output=input%>%layer_lstm(units=50,return_sequences = T)%>%
  layer_lstm(100)%>%
  layer_dense(1)
keras_model(input,output)

 

컴파일은 아래와 같다.

학습에서 줄이고자하는 지표는 LOSS, 최적화 방식은 OPTIMIZER를 의미한다.

# compile
model%>%compile(
  loss='mae',
  optimizer='adam',
  metrics='mae'
)

 

validation 자료로 test자료를 쓰면 안되지만 예제자료이며, 자료수가 충분하지 않아 대체하였다.

학습은 아래와 같이 시키면 된다.

 

batch_size는 한번 학습에 사용할 자료 수, epochs는 전체 자료를 몇 번 반복하는지를 의미한다. 

model%>%fit(x = tr_x,y=tr_y,batch_size = 1,epochs = 3, validation_data =list(te_x,te_y))

 

추가적인 내용

 

딥러닝을 할 때 우리는 그래픽카드를 여러개 사용하는 경우도 존재한다. keras에서는 배치별로 GPU를 따로

 

사용하는 형식으로 돌아간다. 아래는 우선 내 장비 목록을 보는 코드이다.

 

 

나는 이중에서 GPU:0과 GPU:1을 사용하고 싶다고 하자.

with(tf$device('GPU:1'), {
  model=
    keras_model_sequential()%>%
    layer_lstm(units=250,input_shape =c(12,1),return_sequences = T)%>%
    layer_lstm(250,return_sequences = T)%>%
    layer_lstm(250,return_sequences = T)%>%
    layer_lstm(250)%>%
    layer_dense(1)
  model%>%compile(
    loss='mae',
    optimizer=optimizer_adam(lr=0.01),
    metrics='mae'  
  ) 
})

   위와 같이 코드를 실행하면 그래픽카드 두장이 열심히 일하는 것을 볼 수 있다.

 

여기서 끝나면 재미가 없으니, loss function을 커스터마이징 하고 마치겠다.

#loss function costum
# Mean Log Absolute Error
MLAE <- function( y_true, y_pred ) {
  K <- backend()
  K$mean( K$abs( K$log( K$relu(y_true *1000 ) + 1 ) - 
                   K$log( K$relu(y_pred*1000 ) + 1)))
}
# Mean Squared Log Absolute Error
MSLAE <- function( y_true, y_pred ) {
  K <- backend()
  K$mean( K$pow( K$abs( K$log( K$relu(y_true *1000 ) + 1 ) - 
                          K$log( K$relu(y_pred*1000 ) + 1)), 2))
}

losses <- c(keras::loss_mean_squared_error,  
            keras::loss_mean_squared_logarithmic_error, MLAE, MSLAE)

model %>% compile(
  optimizer = "rmsprop",
  loss = losses[3],
  metrics = c("mae")
)

model%>%fit(x = tr_x,y=tr_y,batch_size = 1,epochs = 3, validation_data =list(te_x,te_y))