본문 바로가기

딥러닝

[LSTM] LSTM 나도 한 번 돌려보자

주의! 딥러닝 파트의 게시글은 주로 고생고생해서 구동한 결과이다 보니..

글이 좀 자유분방하게 작성된 편입니다.

자세한 설명은 저보다 chatGPT가 더 잘해줄 거라 믿습니다.

이 글을 찾아오신 여러분도 설명보다는 어떻게 실행하는지가 더 중요하지 않습니까..

 

0. LSTM이란?

Long Short-Trem Momory. 쉽게 이야기하면 주로 시계열 데이터에서 예전 정보 + 최근 정보를 몽땅 가져와서 결과 값을 내는 모델입니다. 
따라서 주가 차트를 학습해서 주가를 예측하거나, 문맥을 학습해서 다음에 나올 단어를 추천해 주거나, 날씨 등을 학습해 내일의 날씨를 예측하는데 참 좋은 모델입니다..

이렇듯 참 좋은 모델인데, 완전 처음부터 실행까지 안내해 주는 게시글이 없어 삽질한 결과를 좀 나눠보려 합니다.

 

1. Requirements.

가장 중요한 부분만 추려봤습니다. 상세 버전은 아래 설치 방법에서 더 자세히 다루겠습니다.

tensorflow, keras -> 얘 때문에 너무 힘들었습니다. 그놈의 의존성, 뭘 그리 버전을 가리는지..

anaconda -> 이 친구가 위의 복잡한 의존성을 그나마 해소해 줬습니다. 콘-맨

pandas -> csv 파일의 전처리를 통해 학습데이터로 활용하기 위해 필요합니다.

scikit-learn -> 데이터를 정규화하고, 학습 데이터 - 테스트 데이터로 나누어 주는 데 사용합니다.

vsCode -> 코드를 좀 편하게 작성하고 싶다면 필요합니다. 본인이 vi, nano 장인이다 하면 패스하셔도 무방합니다.

matplotlib -> 학습 과정을 그래프를 통해 보기 위해서는 필요합니다.

Ubuntu 20.04 -> 다른 버전은 테스트하지 않았습니다만, 혹시 똑같이 따라 했는데도 뭐가 안된다, 설치가 안된다 하면 우분투 버전을 확인해 보시기 바랍니다.

 

2. Installation Instructions.

간단하게 개요를 설명하면 다음과 같습니다.

  a. 리눅스를 클-린 하게 설치한다. (기존 사용하는 거 있으면 사용해도 무방...? 한데 역시 안되면 재설치가 답입니다.)

  b. vsCode 설치. -> 이건 워낙 다른 분들이 친절하게 설명하시기도 했고, 공식 홈페이지에서 다운로드하면 됩니다.

  c. anaconda 설치. -> 아래에 상세 설명하겠습니다.

  d. conda 환경 생성 (python 3.10.* 사용)

  e. 각종 패키지를 '순서대로' 설치

  f. 코드 작성 후 실행.

이렇게 정리해 놓으니 정말 간단해 보이는데요!

문제가 있다면 제 경우

  1. 잘 쓰던 리눅스 머신 -> 설치 실패 

  2. ..? 그래? 가상머신(VMWare) 등판 -> 설치 실패 

  3. 그러면 혹시 윈도우는 되나? -> 설치 실패 

  4. 경건한 마음으로 다시(!) 가상머신 생성 -> 설치 실패.. 의 과정 끝에,

제가 저번에 세팅해 둔 WSL 환경을 통해서 마지막으로 시도하였고, 성공했습니다.

 

아래는 그 절절한 경험담을 소개토록 하겠습니다.

상세 설명은 제가 설명한 WSL 기준이긴 한데, 이 글을 읽는 분들은 리눅스에서 따라 해도 전혀 문제없을 거라 믿습니다.

우선 리눅스 설치랑 VSCode 설치는 제가 작성한 다른 게시물을 참조 바랍니다.

 

1. 윈도우에서 리눅스 사용하기 WSL2 설치 및 사용법 (1) 

 

윈도우에서 리눅스 사용하기 WSL2 설치 및 사용법 (1)

안녕하세요 최원석입니다. 이번 시간에는 WSL에 대해서 알아보도록 하겠습니다. 갑자기 'ROS를 배우는데 웬 리눅스?'라고 의문을 가지실 수도 있습니다. 왜냐하면 ROS2부터는 공식적으로는 윈도우

itgear.tistory.com

2. 윈도우에서 리눅스 사용하기 WSL2 설치 및 사용법 (2)

 

윈도우에서 리눅스 사용하기 WSL2 설치 및 사용법 (2)

안녕하세요 이번 시간에는 실제로 WSL2를 사용하여 Ubuntu 20.04를 설치하는 방법을 알아보겠습니다. WSL을 사용하기 위해서는 윈도우의 버전이 중요한데요, 윈도우 11일 경우 별도의 확인이 필요 없

itgear.tistory.com

 

1. Anaconda 설치

>> wget https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh

>> bash(or zsh) Anaconda3-2019.10-Linux-x86_64.sh 

>> conda init bash(or zsh)

>> source ~/.bashrc(or source ~/.zshrc)

 

2. anaconda 환경 생성

>> conda create -n keras_lstm python=3.10 (지금 깔아보니 3.10.4가 사용되는 듯합니다.)

>> conda activate keras_lstm

 

3. WorkSpace 생성 및 이동

>> cd

>> mkdir lstm

>> cd lstm

 

4. 패키지 설치(요거 중요합니다. 가능하면 순서대로 설치해 주세요)

>> conda update -n base conda (선택사항)

>> conda install -c conda-forge keras (작성일 기준 최신, 정확한 버전 2.9.0)

>> conda install -c conda-forge scikit-learn (작성일 기준 최신, 정확한 버전 1.0.1)

>> conda install -c conda-forge pandas (작성일 기준 최신, 정확한 버전 2.0.3)

>> pip install numpy==1.22.4 (버전 중요합니다.. 이거 때문에 4번 다시 깔았습니다..)

>> pip install tensorflow==2.9.3 (이거 2.11.* 인가 최신으로 설치하면 ml-dtypes, numpy 등 호환성 문제 터집니다..)

>> pip install matplotlib (작성일 기준 최신, 정확한 버전 3.8.0)

 

다행히 이렇게 설치하면 기타 패키지는 알아서 설치되는 모양입니다. 여기까지 왔다면 99.9% 끝났습니다. 

 

5. 파이썬 코드 생성

>> code lstm.py

 

저는 학습 데이터가 하나의 csv 파일로 아래와 같이 위치시켰습니다.

.png -> 학습 과정 그래프를 따로 저장한 것

.csv -> 학습 데이터

.h5 -> weight 파일

.py -> 코드

위는 학습을 한 번 돌린 후 폴더의 모습입니다. 여러분들은 학습이 돌린 적이 없으므로 .py와 .csv만 있으면 되겠습니다.

 

데이터로 사용한 csv 파일은 아래와 같습니다.

여러분들은 학습시키고 싶은 다른 파일이 있겠죠?

 

코드는 아래와 같습니다. (chatGPT 님께 이 공을 돌립니다. 코드는 제가 짠 게 아닙니다.)

import pandas as pd 
import matplotlib.pyplot as plt
import datetime as dt

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential # 얘를 포함해서 아래 임포트 부분이 에러가 많이 나거나, 
from tensorflow.keras.layers import LSTM, Dense  # can not resolve 에러가 종종 보일 수 있습니다.
from tensorflow.keras.optimizers import Adam  #깔끔하게 무시하고 진행하면 됩니다.

# CSV 파일에서 데이터를 로드
data = pd.read_csv('data_41.csv')  # 파일 경로 / 이름을 적절히 수정하세요

# 학습에 사용할 특성 선택(쉽게 말해 엑셀의 열 제목입니다.
features = ['xVelocity', 'yVelocity', 'xAcceleration', 'yAcceleration']

# 입력 데이터(X)와 타깃 데이터(y) 설정
X = data[features].values
y = data[['x', 'y']].values # 이게 결과로 예측할 값입니다.

# 데이터 정규화, 데이터들의 범위가 너무 자유분방하기 때문에 적절한 정규화가 필요합니다.
# 이를 통해 VanishingGradient 문제를 해결할 수 있다고합니다. 저도 책에서 봤습니다.
scaler = StandardScaler()
X = scaler.fit_transform(X)
y = scaler.fit_transform(y)

# 학습 및 테스트 데이터 분할; 학습을 8 테스트를 2
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)


# LSTM 모델 생성
model = Sequential()

#첫번째 레이어는 입력 데이터의 형태에 대한 정보가 필요합니다.
#다음 레이어 부터는 자동으로 형태를 추정할 수 있기 때문에, 명시적으로 작성할 필요는 없습니다.
#여기서 처음 레이어는 LSTM 입니다. 입력 형태가 X_train ... 
#여러분들은 이 input_shape을 적당하게 수정해주시면 됩니다.
model.add(LSTM(64, input_shape=(X_train.shape[1], 1), return_sequences=True))
model.add(LSTM(32, return_sequences=False))
model.add(Dense(2))  # 2는 x와 y의 출력 차원입니다.


model.summary()


# 모델 컴파일,
# 다음은 loss 함수와 optimizer를 설정할 수 있습니다.
# optimizer로는 가장 많이 사용하는 adam을(관성이 있어 local minima에 빠질 확률을 줄여줍니다.),
# loss함수로는 mse를 사용합니다.(추후 변경가능, 가장 간단한게 mse, mae입니다.)
# learning_rate는 적절하게 조정해주세요.
model.compile(optimizer=Adam(learning_rate=0.001), loss='mse')

# 아래는 모델 학습을 위한 코드입니다. 0.1은 학습데이터에서 다시 10%를 validation data로 사용하기 위해 빼놓습니다.
# Overfitting에 빠질 확률을 줄여주는 학습법이라 할 수 있습니다.
# epochs 만큼 학습합니다.
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.1)

# 모델 평가
loss = model.evaluate(X_test, y_test)
print(f'Test Loss: {loss}') # loss 출력
 
# 아래는 모델을 저장할 때, 저장 파일 이름이 겹치지 않도록 현재 시간을 사용하여 저장합니다.
x = dt.datetime.now()
x = x.strftime("%Y_%m_%d_%H:%M:%S")
model.save_weights(f'lstm_weights_{x}.h5') # 모델 저장

# 예측 수행
predictions = model.predict(X_test)

# 예측된 값을 원래 스케일로 복원 (학습할 때 정규화를 시켜서 학습을 했으니...)
predictions = scaler.inverse_transform(predictions)
y_test = scaler.inverse_transform(y_test)

# 원래 스케일로 복원한 예측값
x_pred = predictions[:, 0]
y_pred = predictions[:, 1]

# 실제 데이터
x_true = y_test[:, 0]
y_true = y_test[:, 1]

# 시간 (timestamp)을 표현하는 변수가 있다면 해당 시간을 x축으로 사용할 수 있습니다.
# 예를 들어, data['frame']에서 시간 정보를 얻어와서 x축으로 사용할 수 있습니다.

# 그래프 그리기
plt.figure(figsize=(12, 6))
plt.plot(x_true, label='True x', color='blue') # 실제 데이터를 출력
plt.plot(y_true, label='True y', color='green') # 실제 데이터를 출력
plt.plot(x_pred, label='Predicted x', color='red', linestyle='--') # 예측값을 출력
plt.plot(y_pred, label='Predicted y', color='purple', linestyle='--') # 예측값을 출력

plt.legend()
plt.title('X and Y Prediction vs. True Values')
plt.xlabel('Time')  
plt.ylabel('Value')
plt.grid(True)

plt.savefig(f'{x}.png') # 결과 이미지를 저장합니다.
 

이렇게 코드를 작성하고, run을 하면 인터프리터를 선택하는 창이 뜰 겁니다. 

아래처럼 만들어둔 conda 환경을 선택합니다.

모델이 아주 잘 학습되고 있는 걸 보실 수 있습니다.

loss 값은 말이 안 되지만, 뭐 어떤 건 괜찮았습니까ㅎ..

제 역할은 여기까지입니다. 여러분들도 훌륭한 모델을 만들어 세상을 좋은 방향으로 변화시킬 수 있기를 바랍니다.

 

궁금한 점, 설치하다 막힌 거 댓글로 알려주시면, 시간 나는 대로 확인해 보겠습니다.

(저도 4시간 끙끙거렸기 때문에, 볼법한 에러는 다 만난 듯싶습니다.)

 

result : epoch 15.

그런데 어찌 모델이 썩 총명하진 않은 듯싶습니다..

'딥러닝' 카테고리의 다른 글

[LSTM] WSL에서 GPU 사용하기  (1) 2023.11.07