들어가며
오늘은 교수님과의 마지막 수업날이다. 임시저장이 작동하지 않은 채 자꾸만 튕겨서 같은 글을 3번째 쓰고있다는 것이 참 착잡하지만 어쩔 수 없다. 복습 여러번 하면 오히려 좋은 것 같기도 하다^^
삼성 주가 데이터 예측
삼성의 주가데이터를 2016년부터 2020년치와 2020년부터 가장 최근 데이터 총 2가지를 준비해보았다. 실제로 사용할 데이터는 가장 최근 데이터가 포함된 것으로 사용할 것이다. 훈련 데이터는 뒤에서부터 200개, 테스트 데이터는 훈련데이터를 제외한 나머지의 데이터들(약 1900개)로 사용한다.
import FinanceDataReader as fdr
import numpy as np
from matplotlib import pyplot as plt
from sklearn.preprocessing import MinMaxScaler
import keras
# 2016-2020 삼성 주가 데이터 불러오기
samsung = fdr.DataReader(symbol='005930', start='01/01/2016', end='12/23/2020') # 삼성
print(samsung)
print(samsung.shape)
print(samsung.columns) # pandas dtype (object: 최상위클래스)
print(samsung[['Open']])
open_values = samsung[['Open']]
print(open_values)
print(open_values.shape)
# 2016-최근 삼성 주가 데이터 불러오기
samsung = fdr.DataReader(symbol='005930', start='01/01/2016', end=None) # 삼성
print(samsung)
print(samsung.shape)
print(samsung.columns) # pandas dtype (object: 최상위클래스)
print(samsung[['Open']])
open_values = samsung[['Open']]
print(open_values)
print(open_values.shape)
# 데이터가 너무 큼(간격, 값) => 정규화
# MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1)) # 최대값 1, 최소값 0
scaled_open_values = scaler.fit_transform(X=open_values)
print(scaled_open_values)
print(scaled_open_values.shape)
TEST_SIZE = 200
# 훈련 데이터, 테스트 데이터 : 테스트 200
train_data = scaled_open_values[:-TEST_SIZE] # 뒤에서부터 200개
test_data = scaled_open_values[-TEST_SIZE:]
print(train_data)
print(train_data.shape) # (1914)
print(test_data)
print(test_data.shape) # (200)
`make_feature`함수로 훈련 데이터를 사용하여 LSTM모델에 입력할 수 있는 형태의 데이터 셋을 생성한다.
# RNN - LSTM : 입력데이터 타입이 Tensor 3
def make_feature(open_values, windowing) -> tuple:
train = list()
test = list()
for i in range(len(open_values) - windowing):
train.append(open_values[i: i+windowing])
test.append(open_values[i+windowing])
print(train)
print(test)
return np.array(train), np.array(test)
이제 Long Short Term Memory 모델을 생성하고 입력층과 은닉층, 그리고 출력층을 모델에 추가한다. 그리고 손실함수로 mean square error, optimizer로 adam을 사용하여 학습을 시키고 학습된 모델을 저장한다.
# LSTM으로 구현하기
model = keras.models.Sequential(name='LSTM_MODEL')
model.add(keras.Input(shape=(X_train.shape[1], 1), name='INPUT'))
# LSTM units=32, cell=32 -> 메모리 개수
model.add(keras.layers.LSTM(units=32, return_sequences=True,
activation='tanh', name='LAYER1'))
model.add(keras.layers.LSTM(units=16, return_sequences=False,
activation='tanh', name='LAYER2'))
model.add(keras.layers.Dense(units=1, activation='sigmoid', name='OUTPUT'))
model.summary()
# 모델 학습
model.compile(loss='mse', optimizer='adam')
# model.fit(x=X_train, y=y_train, epochs=100, batch_size=16)
# model.save('LSTM_MODEL.keras')
model_2 = keras.models.load_model('LSTM_MODEL.keras')
학습된 모델을 바탕으로 정답과 예측을 그래프를 통해 확인한 모습이다. 완전히 같지는 않지만 어느정도 잘 따라가는 것을 알 수 있다.
# 테스트 진행
(X_test, y_test) = make_feature(open_values=test_data, windowing=30)
predictions = model_2.predict(x=X_test)
print(predictions)
print(predictions.shape)
# 그래프로 정답과 예측 확인
plt.figure(figsize=(10,8))
plt.plot(y_test, label='STOCK PRICE', color='blue')
plt.plot(predictions, label='Predictions', color='red')
plt.legend()
plt.show()
사람 이미지와 동물 이미지 학습 및 분류
이번엔 각 이미지를 학습하여 어떤게 사람 이미지인지를 분류해내는 모델을 만들어 볼 것이다. 이미지 분류에는 CNN이 적합하기 때문에 이 모델을 사용한다.
먼저 사람 얼굴 이미지 파일 15개를 가져오고 리스트 변수에 저장해준다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
import keras
# 얼굴 이미지 파일 가져오기
face_images = list()
for i in range(15):
file = './faces/' + 'img{0:02d}.jpg'.format(i + 1)
img = cv2.imread(file)
img = cv2.resize(img, (64, 64))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR을 RGB로 변환
face_images.append(img)
아래는 이미지 그래프를 그리는 함수이다. 지정한 행과 열의 크기만큼 이미지를 나열해서 출력해준다.
# 이미지 그래프 그리는 함수
def plot_images(n_row:int, n_col:int, image:list[np.array]) -> None:
fig = plt.figure()
(fig, ax) = plt.subplots(n_row, n_col, figsize=(n_col, n_row))
for i in range(n_row):
for j in range(n_col):
if n_row <= 1:
axis = ax[j]
else:
axis = ax[i,j]
axis.get_xaxis().set_visible(False)
axis.get_yaxis().set_visible(False)
axis.imshow(image[i * n_col + j])
plt.show()
return None
# 얼굴 이미지 그래프 그리기
plot_images(n_row=3, n_col=5, image=face_images)
마찬가지로 동물 이미지도 불러와서 리스트에 담은 후 이미지 그래프를 그려서 출력해본다.
# 동물 이미지 불러오기
animal_images = []
for i in range(15):
file = './animals/' + 'img{0:02d}.jpg'.format(i + 1)
img = cv2.imread(file)
img = cv2.resize(img, (64, 64))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR을 RGB로 변환
animal_images.append(img)
# 동물 이미지 그래프 그리기
plot_images(n_row=3, n_col=5, image=animal_images)
각 사람, 동물 이미지데이터들을 수치형 즉, 0과 1로 변환하여 학습 데이터와 정답 데이터로 만들어준다. 이 때 만들어진 X와 y는 numpy데이터가 아니기 때문에 numpy로 변환해줌으로써 데이터 형태를 확인한다.
# 학습 시킬 데이터와 정답 데이터 만들기
X = face_images + animal_images # 얼굴이미지+동물이미지 병합
y = [[1,0]] * len(face_images) + [[0,1]] * len(animal_images) # 원핫 인코딩 방식처럼
# print(y)
# print(y.shape)
# numpy가 아니므로 shape 사용x
# numpy로 변환
X = np.array(X)
y = np.array(y)
print(y)
print(y.shape)
이미지들을 학습시키기 위해 CNN모델을 생성하고, 학습 횟수를 1,000번으로 설정한 후 모델을 저장해준다.
# CNN모델 만들기
model = keras.models.Sequential([
keras.Input(shape=(64, 64, 3)), # color이미지(64 x 64)
keras.layers.Conv2D(filters=32, kernel_size=(3, 3)),
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2),
keras.layers.Conv2D(filters=32, kernel_size=(3, 3)),
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2),
keras.layers.Conv2D(filters=32, kernel_size=(3, 3)),
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2),
keras.layers.Conv2D(filters=32, kernel_size=(3, 3)),
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2),
keras.layers.Flatten(),
keras.layers.Dense(units=64, activation='relu', name='LAYER1'),
keras.layers.Dense(units=32, activation='relu', name='LAYER2'),
keras.layers.Dense(units=2, activation='softmax', name='OUTPUT')
], name='FACE_CNN')
# 모델 학습이 끝났을 경우, 주석 처리
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 1000번 학습된 CNN모델 생성
history = model.fit(x=X, y=y, epochs=1_000)
model.save('FACE_DETECTOR.keras')
학습된 모델에 사용하기 위한 예시 이미지 10개를 불러온다. 이미지 픽셀값의 크기를 통일 시키기 위해 사이즈 64 x 64로 지정해준다. open-cv로 이미지를 불러오기 되면 BGR로 읽기 때문에 `cv2.cvtColor(img, cv2.COLOR_BGR2RGB)` 를 사용함으로써 RGB로 변환해주어야 한다.
# 성능 테스트 : 예제 파일을 읽어와서 이미지 테스트 하기
# 예제 이미지 가져오기
example_images = list()
for i in range(10):
file = './examples/' + 'img{0:02d}.jpg'.format(i + 1)
img = cv2.imread(file)
img = cv2.resize(img, (64, 64))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR을 RGB로 변환
example_images.append(img)
# example_images python 파일
example_images = np.array(example_images)
plot_images(n_col=5, n_row=2, image=example_images)
학습된 모델을 사용하여 테스트 이미지를 넣는다. 아래는 예측할 이미지들은 사람 얼굴이므로 사람으로 분류된 이미지들을 2 x 5크기의 그래프로 출력시킨 결과이다. 말이랑 불가사리 제외한 4개의 이미지만이 사람얼굴로 잘 분류해준 것을 확인할 수 있었다.
# 학습완료한 모델 가져오기
model_2 = keras.models.load_model('FACE_DETECTOR.keras')
predict_images = model_2.predict(x=example_images)
print(np.round(predict_images))
# 2 x 5 이미지 그래프 그리기
(fig, ax) = plt.subplots(2, 5, figsize=(10, 4))
for i in range(2):
for j in range(5):
axis = ax[i, j]
axis.get_xaxis().set_visible(False)
axis.get_yaxis().set_visible(False)
if predict_images[i * 5 + j][0] > 0.5:
axis.imshow(example_images[i * 5 + j])
plt.show()
마무리
생각보다 이미지를 잘 분류해주지는 못해서 약간은 아쉬운 감이 없잖아 있지만, 그래도 이미지 분류를 통해 시각적으로 CNN을 배워볼 수 있어서 좋았다. 내일부터는 미니프로젝트 시작이니 지금까지 배운 부분을 한번씩 되짚어보는 시간을 가져야겠다.
'ABC부트캠프 테크노트' 카테고리의 다른 글
[26일차] ABC부트캠프 : 미니프로젝트 발표 (0) | 2024.08.08 |
---|---|
[25일차] ABC부트캠프 : 미니 프로젝트 준비 (0) | 2024.08.07 |
[23일차] ABC부트캠프 : 딥러닝2 (0) | 2024.08.06 |
[22일차] ABC부트캠프 : 딥러닝1 (0) | 2024.08.02 |
[21일차] ABC부트캠프 : ESG포럼 & 세미나3 (0) | 2024.08.02 |