본문 바로가기
Programming 개발은 구글로/기타 정보

[WEB+AI] 30일차 딥러닝 + RNN

by 40대직장인 2024. 11. 22.

딥러닝 - RNN

 

강사: 이숙번님

 

1. RNN(Recurrent Neural Network) - 주가 예측 모델

  : 순환 신경망은 시계열 데이터나 순차 데이터를 처리하는 데 특화된 딥러닝 모델입니다.

 

  - RNN은 이전 시간의 정보를 현재 시간의 계산에 반영하기 위해 순환 구조를 가지며, 데이터를 순차적으로 처리하고, 과거 상태를 기억할 수 있습니다.

  - 데이터 vs 순차데이터

 1.1. 순차데이터(Sequential Data)

  • sequential data - 순서가 의미가 있는 데이터
    • temporal sequence - 시간적 의미가 있는 데이터
    • time series - 일정한 주기가 존재하는 데이터
  • resampling을 통해 temporal sequence를 time series로 변환할 수 있음.
!pip install finance-datareader

 

import FinanceDataReader as fdr 

df = fdr.DataReader('030200', '2023-08-01') # KT 주식
df.head()

 

 

# 결과

 

 

import FinanceDataReader as fdr
import numpy as np

# KT(030200) 전체 (1999-05-31 ~ 현재)
df = fdr.DataReader('030200')
data = df.values[:, :-1]
print(data.shape)

# train, val, test 분리
train, val, test = data[:-900], data[-900:-600], data[-600:]
print(train.shape, val.shape, test.shape)

# normalize - 표준화
norm = {'std': train.std(axis=0), 'mean': train.mean(axis=0)}
train = (train - norm['mean']) / norm['std']
val = (val - norm['mean']) / norm['std']
test = (test - norm['mean']) / norm['std']

# 결과
(6000, 5)
(5100, 5) (300, 5) (600, 5)

 

 

# 독립/종속 분리
x_train = np.array([train[i:i+10] for i in range(len(train) - 10)])
y_train = np.array([train[i+10, 3] for i in range(len(train) - 10)])
print(x_train.shape, y_train.shape)

x_val = np.array([val[i:i+10] for i in range(len(val) - 10)])
y_val = np.array([val[i+10, 3] for i in range(len(val) - 10)])
print(x_val.shape, y_val.shape)

x_test = np.array([test[i:i+10] for i in range(len(test) - 10)])
y_test = np.array([test[i+10, 3] for i in range(len(test) - 10)])
print(x_test.shape, y_test.shape)

# 결과
(5090, 10, 5) (5090,)
(290, 10, 5) (290,)
(590, 10, 5) (590,)

 

import tensorflow as tf

X = tf.keras.layers.Input(shape=[10, 5])
H = tf.keras.layers.SimpleRNN(32)(X)
Y = tf.keras.layers.Dense(1)(H)

model = tf.keras.models.Model(X, Y)
model.compile(loss='mse')

 

model.fit(x_train, y_train, epochs=100, validation_data=(x_val, y_val))

 

model.evaluate(x_test, y_test)

 

# 결과

0.004140088334679604

 

df = fdr.DataReader('030200')
data = df.values[:, :-1]
print(data.shape)   
data

# 결과
(6000, 5)
array([[  79900.,   82000.,   78800.,   80000.,  467578.],
       [  81800.,   82300.,   79700.,   80000.,  448240.],
       [  80100.,   80900.,   79000.,   80500.,  274798.],
       ...,
       [  41750.,   43650.,   41700.,   43300., 1325662.],
       [  43300.,   44750.,   43300.,   44000., 1126037.],
       [  44600.,   45150.,   44200.,   44500.,  552703.]])

 

 

tx = [train[i:i+10] for i in range(len(train) - 10)]
ty = [train[i+10, 3] for i in range(len(train) - 10)]   

tx = []
for i in range(len(train) - 10):
    tx.append(train[i:i+10])

ty = []
for i in range(len(train) - 10):
    ty.append(train[i+10, 3])   

print(tx[0], ty[0])

# 결과
[[ 4.16397712  4.23101124  4.19440169  4.17112507 -0.49828924]
 [ 4.354963    4.26047054  4.2870496   4.17112507 -0.52000775]
 [ 4.1840809   4.12299381  4.21499011  4.22135778 -0.71480043]
 [ 4.14387334  4.02479614  4.03998852  3.97019424 -0.66361628]
 [ 3.78200535  3.92659847  3.91645798  3.81949612 -0.58171197]
 [ 3.97299124  4.18191241  4.07087115  4.32182319 -0.39443058]
 [ 4.25444412  4.27029031  4.14293063  4.41224207 -0.21520743]
 [ 4.07351012  4.21137171  4.2046959   4.23140432 -0.52324003]
 [ 4.47558567  4.34884845  4.36940329  4.23140432 -0.63297924]
 [ 4.29465167  4.23101124  4.36940329  4.27159049 -0.48657756]] 4.171125070015443

 

  - 마지막 tx[5089], ty[5089] => train 5100

 

 1.2. Nomalize

  : 평균을 0으로 다른 값들을 표준편차 1로 변환

 

 

2. Vanilla RNN

 

  • 순환 구조: 이전의 출력을 현재의 입력과 함께 사용.
  • 가중치 공유: 한 개의 셀 = 한 개의 수식. 하나의 셀을 반복해서 사용
  • 단기 기억: 짧은 시퀀스 데이터 학습에 사용

 

X = tf.keras.layers.Input(shape=[10, 5])
H = tf.keras.layers.SimpleRNN(8)(X)
Y = tf.keras.layers.Dense(1)(H)

 

  • 10개의 행은 RNN 내에서 10번의 입력
  • 마지막은 앞 출력 8개와 5개를 합쳐서 총 13개의 출력이 나옴.
  • 112 = 8 * (5 + 8 + 1)

 

model.fit(x_train, y_train, epochs=100, validation_data=(x_val, y_val))

 

...

 

model.evaluate(x_test, y_test)

 

# 결과

0.004593954421579838

 

import matplotlib.pyplot as plt

y_pred = model.predict(x_test)

plt.figure(figsize=(10, 5))
plt.plot(y_pred)
plt.plot(y_test)
plt.legend(['pred', 'real'])
plt.show()

 

 

 

3. RNN - 이미지 분류 모델

  - RNN 기울기 소실(RNN activation tanh)

 

  • 원인은 activation 함수 tanh에 있음.
  • 시퀀스가 길어질 때, 앞쪽 입력값의 영향이 0에 수렴한다. 

 

 

 

4. LSTM(long-short term memory)

: LSTM은 순환 신경망(RNN)의 일종으로, 시퀀스 데이터를 처리하기 위해 설계된 딥러닝 모델입니다.

 

  - 기억(Cell State)을 통해 과거의 중요한 정보를 오래 유지하고, 불필요한 정보를 제거하며 기울기 소실(Vanishing Gradient) 문제를 효과적으로 해결합니다.

 

 

 

import tensorflow as tf

X = tf.keras.layers.Input(shape=[28, 28])
H = tf.keras.layers.LSTM(32)(X)
Y = tf.keras.layers.Dense(10, activation="softmax")(H)

model = tf.keras.Model(X, Y)
model.compile(loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.summary()

 

 

 

 

  - 잊을 것은 잊고, 기억할 것만 기억한다.

 

 

“기억”

1. 현재 턴의 입력 정보

2. 기억 업데이트

  a. 입력 정보를 토대로 기억에서 얼마나 잊을지 결정

  b. 입력 정보를 토대로 기억에서 새로운 기억을 추가

3. 입력 정보를 토대로 업데이트된 기억에서 꺼낸다.

 

 

 

 4.1. 게이트 모델 만들기

  - Gate - sigmoid의 재발견

  • 정보를 '선택적으로' 으로 통과시키는 관문
  • Sigmoid 활성함수와 곱셈으로 이루어짐.
  • LSTM에는 3종류의 gate 사용(forget, input, output gate)

 

 

 

X = tf.keras.Input(shape=[13])
H = tf.keras.layers.Dense(8, activation='relu')(X)
H = tf.keras.layers.Dense(8, activation='relu')(H)
G = tf.keras.layers.Dense(8, activation='sigmoid')(H) # Gate의 활용
H = tf.keras.layers.Dense(8, activation='relu')(G * H)
Y = tf.keras.layers.Dense(1)(H)
model = tf.keras.Model(X, Y)
model.compile(loss='mse')
model.summary()

 

 

# 결과

 


출처: AI Hub 교육과정 - WEB+AI (위 내용이 문제가 된다면 댓글에 남겨주세요. 바로 삭제조치하도록 하겠습니다.)

 

 

댓글