-
시계열 이미지 처리 Baseline(RNN + CNN)딥러닝/딥러닝 Baseline 2024. 6. 27. 15:09
오랜만에 피드를 올린다.
시계열 이미지 처리의 Baseline에 대해 설명 및 코드 구현을 하고자 한다.
시계열 이미지는 쉽게 말해 비디오라고 보면 된다.
비디오는 연속적인 이미지프레임을 겹쳐놓은 포맷이다.
따라서 fps (frame per second) 값에 비디오의 자연스러움이 달라지는것을 같은 맥락으로 이해할 수 있다.
ex) fps = 60 이면 1초에 60장 이미지
시계열 이미지를 처리하는 예는 일반적으로
1) CCTV 영상의 이상 감지
2) 식물이 자라나는 이미지를 통해 성장 속도 및 생육 환경 예측
3) 동작 / 패턴 분석
정도로 볼 수 있다,
기술적으로 우선 이미지이므로 CNN 구조가 필요하다. 그리고 직전 이미지들이 직후 이미지에 영향을 주는 즉, Recurrent한 데이터 구조이므로 RNN 방식이 필요하다.
따라서 이미지를 먼저 CNN 구조로 Fully Connected Layer로 Flatten한 후에 이를 RNN의 input으로 활용해서 최종적으로 추론 (회귀 또는 분류)을 진행한다.
요약하면 아래와 같다.
1) 이미지 → numpy array 변환
2) CNN 모델 구조 구축
3) RNN (LSTM) 모델 구조 구축
4) 이미지(input) → CNN 모델 구조 → 최종 output layer → RNN LSTM 구조 → Inference(추론)
본 포스팅에서는 최대한 심플하고 또 심플한 형태로 작성하고자 한다.
주의할 것은 주요 차원 에러를 방지하기 위해 각 input , output 의 차원을 잘 고려해서 실수 없이 진행하는 것이다.
아래 코드는 간단한 이상 감지( 0,1 binary classification) 관련 내용이다.
import pandas as pd import numpy as np from glob import glob PATH = "실제 이미지 file path" image_path = glob(PATH + "/*") train_image = pd.DataFrame([]) # image_path 에 대한 각 label 값은 image_label로 적용 train_image["image_path"] = image_path train_image["image_label"] = image_label # 이미지 숫자가 충분히 작다고 보고 (클 경우엔 sequence 응용) image_path = train_image["image_path"].values image_label = pd.factorize(train["image_label"])[0] IMAGE_SIZE = 64 # 본 포스팅에서는 64x64 로 가정 import cv2 image_array_list = [] for i in range(len(image_path)): image = cv2.cvtColor(cv2.imread(image_path[i]), cv2.COLOR_BGR2RGB) image = image / 255.0 image = cv2.resize(image , (IMAGE_SIZE , IMAGE_SIZE)) image_array_list.append(image) image_array = np.array(image_array_list) import tensorflow as tf from tensorflow.keras.models import Model, Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, LSTM, TimeDistributed, Dense, Input from tensorflow.keras.optimizers import Adam # CNN 모델 정의 def create_cnn_model(input_shape): model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=input_shape)) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) return model cnn_input_shape = (64,64,3) cnn_model = create_cnn_model(cnn_input_shape) # 시계열 CNN 모델 정의 lstm_input_shape = (len(image_array) , 64, 64, 3) inputs = Input(shape=lstm_input_shape) time_distributed = TimeDistributed(cnn_model)(inputs) # LSTM 레이어 추가 lstm_out = LSTM(128, return_sequences=True)(time_distributed) # 이상 징후 감지를 위한 추가 Dense 레이어(0,1 둘 중 하나로) dense_out = TimeDistributed(Dense(1, activation='sigmoid'))(lstm_out) # 최종 모델 정의 model = Model(inputs, dense_out) # 모델 컴파일 model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy']) # 모델 요약 출력 model.summary() # 모델 학습 model.fit(image_array, image_label, epochs=10, batch_size= 4) # train test split 으로 train / validation 데이터셋 구분해서 나눠서 추가로 validation data set까지 추가해서 모델을 개선시킬 수 있다. model.predict(test_image_array) # 왼쪽과 같이 추론을 할 수 있고, LSTM 입력할때 slicing window를 적용해서 학습시키는 방법을 적용할 수도 있다.
'딥러닝 > 딥러닝 Baseline' 카테고리의 다른 글
5분이면 끝내는 RNN 모델 문제 풀기 (0) 2022.11.10 TEST IMAGE Sequence 상속 받아서 예측하기 (CNN Baseline 연계) (0) 2022.11.10 CNN 신경망 Baseline (0) 2022.11.10