AI 개발 공부 공간

AI, 머신러닝, 딥러닝, Python & PyTorch, 실전 프로젝트

딥러닝/딥러닝: 시계열 데이터

LSTM 모델 생성과 연속적 sequence 데이터 처리

qordnswnd123 2025. 1. 23. 20:19

1. 연속적 시퀀스 데이터

 

 

LSTM네트워크는 개별 LSTM셀들이 연결된 구조로, 시퀀스 데이터의 각 요소를 순차적으로 처리하면서 정보를 전달합니다.

LSTM 네트워크는 각 시점의 입력 데이터와 이전 셀의 출력을 받아 상태를 업데이트하고, 업데이트된 상태를 다음 셀로 전달하면서 데이터의 흐름을 조절합니다.

 

1) 데이터 로드( 서울시 평균 기온 예측 대회 데이터)

import numpy as np
import pandas as pd 
import random 

df_weather = pd.read_csv('sample_weather_data.csv')
features = ['humidity','rainfall','wspeed','temperature']  

print(df_weather.head())
print(f"데이터 갯수 : {len(df_weather)}")
          day  humidity  rainfall  wspeed  temperature
0  2021-01-01      64.0       0.0     2.0         -4.2
1  2021-01-02      38.5       0.0     2.6         -5.0
2  2021-01-03      45.0       0.0     2.0         -5.6
3  2021-01-04      51.4       0.0     1.7         -3.5
4  2021-01-05      52.8       0.0     2.9         -5.5
데이터 갯수 : 730

 

2) 연속적 시퀀스(Sequence) 데이터 생성

시퀀스 데이터란 시간 순서에 따라 정렬되어 있으며, 각 데이터 포인트가 이전의 데이터 포인트와 시간적 연관성을 가지고 있는 데이터 집합입니다.

이러한 특성은 시계열 데이터 분석, 음성 인식, 언어 변역 등에 매우 중요하며, 특히 날씨 예측과 같은 문제에서는 연속된 입력과 이상 조건을 기반으로 미래의 기온을 예측하는 데 사용됩니다.

RNN(Recurrent Neural Network)과 LSTM(Long Short-Term Memory)과 같은 순환 신경망은 시퀀스 데이터의 패턴을 학습하고 과거 정보를 기억함으로써, 시간에 따른 데이터의 특성을 효과적으로 모델링할 수 있습니다.

이 모델들은 각 시점에서 입력과 함께 이전 시점의 출력을 입력으로 받아들이는 구조로, 데이터 간의 시간적 종속성을 내재적으로 학습할 수 있습니다.

시퀀스 데이터를 생성하는 이유는 모델이 과거 데이터의 시퀀스를 기반으로 미래 값을 예측할 수 있도록 학습 구조를 구성하기 위해섭니다.

예를 들어, 과거 일간의 기상 데이터를 바탕으로 다음 날의 기온을 예측하는 경우, 이 시퀀스 안의 패턴을 통해 기온의 변화를 보다 정확히 예측할 수 있습니다.

 

아래는 데이터 프레임에서 시퀀스 데이터를 생성하는 코드 블록입니다.
'i'를 시작 인덱스로 사용하여 주어진 'seq_length' 길이만큼의 데이터를 슬라이싱하여 시퀀스 데이터 '_x'를 생성하겠습니다.

그리고 'i + seq_length'를 인덱스로 사용하여 다음 포인트의 기온을 '_y'로 설정하겠습니다.

# 시퀀스 데이터 생성 함수
def build_sequence_dataset(df, seq_length):
    dataX = []
    dataY = []
    for i in range(0, len(df) - seq_length):
        _x = df.iloc[i:i + seq_length].values  # 시퀀스 데이터
        _y = df.iloc[i + seq_length]['temperature']  # 다음 포인트의 기온을 레이블로 사용
        dataX.append(_x)
        dataY.append(_y)
    return np.array(dataX), np.array(dataY)

# 시퀀스 길이 정의
seq_length = 6  # 과거 6일의 데이터를 기반으로 다음날의 기온을 예측
# 데이터셋 생성
sequence_dataX, sequence_dataY = build_sequence_dataset(df_weather[features], seq_length)
# 생성된 시퀀스 데이터의 첫 번째 요소를 출력하여 실습 예제 확인
print(f"sequence_dataX 형태 : {sequence_dataX.shape}")
print(f"sequence_dataX 갯수 : {len(sequence_dataX)}")

print("첫번째 sequenceX:")
print(sequence_dataX[0])
print("첫번째 sequenceY:")
print(sequence_dataY[0])
sequence_dataX 형태 : (724, 6, 4)
sequence_dataX 갯수 : 724
첫번째 sequenceX:
[[64.   0.   2.  -4.2]
 [38.5  0.   2.6 -5. ]
 [45.   0.   2.  -5.6]
 [51.4  0.   1.7 -3.5]
 [52.8  0.   2.9 -5.5]
 [54.6  2.3  2.4 -7.4]]
첫번째 sequenceY:
-14.5

 

※ 결과 해석

  • sequence_dataX 형태 : 출력된 (724, 6, 4) 형태는 sequence_dataX 배열이 724개의 시퀀스를 포함하고 있으며, 각 시퀀스는 6일 동안의 데이터를 나타내고, 각 일자는 4개의 특성(습도, 강수량, 풍속, 기온)을 포함하고 있음을 의미합니다. 이는 과거 6일간의 날씨 데이터를 연속적으로 포함하고 있어, 이를 기반으로 다음날의 기온을 예측하는 데 사용됩니다.
  • sequence_dataX 개수 : 724는 전체 데이터에서 시퀀스 길이만큼 제외된 후 남은 데이터의 수입니다. 전체 데이터에서 처음 6일간의 데이터를 제외해야 예측에 필요한 전체 시퀀스를 형성하기 위해 사용되므로, 실제 예측 가능한 데이터 포인트의 수는 전체 데이터 수에서 6을 뺀 값입니다.
  • 첫 번째 sequenceX : -14.5는 첫 번째 시퀀스 데이터의 개별적 값들을 보여줍니다. 이 배열은 첫 6일 동안의 습도, 강수량, 풍속, 기온 값을 포함하고 있으며, 예를 들어 첫 번째 sequenceX 값이 [64.0, 0.2, 2.0, -4.2]일 경우, 첫 번째 습도가 64.0, 강수량 0.2, 풍속 2.0, 기온이 -4.2°C임을 나타냅니다.
  • 첫 번째 sequenceY : -14.5는 첫 번째 시퀀스 데이터에 이어지는 다음날의 기온을 나타냅니다. 이 값은 LSTM 모델이 해당 시퀀스 데이터를 기반으로 예측해야 할 기온 값으로 사용됩니다.

 

3) nn.LSTM 모듈 통한 LSTM 네트워크 인스턴스 생성

nn.LSTM 모듈은 PyTorch 라이브러리에서 제공하는 LSTM 네트워크를 구성하는 표준 모듈입니다.

이 모듈은 이전 스테이지에서 살펴본 LSTMCell의 개념을 확장하여 사용합니다.

LSTMCell은 LSTM 네트워크의 기본 요소로, 각 시점에서 단일 시퀀스 데이터 처리를 담당하며, 입력 게이트, 망각 게이트, 출력 게이트 등 LSTM의 주요 게이트 메커니즘을 구현합니다.

반면, nn.LSTM은 여러 시점의 데이터를 처리할 수 있는 전체 네트워크를 자동으로 관리합니다.

이 모듈은 내부적으로 여러 개의 LSTMCell을 포함하며, 시퀀스의 요소를 차례대로 처리하고 각 시점의 상태를 자동으로 유지합니다.

이를 통해 개발자는 시퀀스 데이터를 각 시점별로 개별적으로 처리하는 복잡한 과정 없이, 전체 시퀀스를 효율적으로 학습할 수 있는 모델을 구축할 수 있습니다.

import torch
import torch.nn as nn

num_features = len(features)
num_hidden = 10

# LSTM 모듈 초기화
model_lstm = nn.LSTM(input_size=num_features, hidden_size=10, num_layers=1)
print("모델 구조:")
print(model_lstm)
모델 구조:
LSTM(4, 10)

 

※ 결과 해석

  • input_size : 모델에 입력될 특성의 수입니다. 이 예제에서는 날씨 데이터의 특성(습도, 강수량, 풍속, 기온) 네 가지를 사용하므로 input_size는 4입니다.
  • hidden_size : LSTM 네트워크의 hidden state의 크기입니다. 이 값은 네트워크가 내부적으로 유지하는 메모리의 용량을 결정하며, 크게 설정할수록 더 많은 정보를 저장할 수 있지만 계산 비용이 증가합니다. 예제에서는 10으로 설정되어 있습니다.
  • num_layers : 네트워크의 레이어 수입니다. 여러 개의 LSTM 레이어를 쌓아서 더 복잡한 패턴을 학습할 수 있으며, 이 예제는 num_layers를 1로 가정합니다.

 

이제 생성된 LSTM 모델의 매개변수 구조를 출력해보겠습니다.

for name, param in model_lstm.named_parameters():
    print(f"{name}: {param.shape}")

# 특정 가중치에 직접 접근

print("weight_ih_l0 shape:", model_lstm.weight_ih_l0.shape)
print("weight_hh_l0 shape:", model_lstm.weight_hh_l0.shape)
print("bias_ih_l0 shape:", model_lstm.bias_ih_l0.shape)
print("bias_hh_l0 shape:", model_lstm.bias_hh_l0.shape)
weight_ih_l0: torch.Size([40, 4])
weight_hh_l0: torch.Size([40, 10])
bias_ih_l0: torch.Size([40])
bias_hh_l0: torch.Size([40])
weight_ih_l0 shape: torch.Size([40, 4])
weight_hh_l0 shape: torch.Size([40, 10])
bias_ih_l0 shape: torch.Size([40])
bias_hh_l0 shape: torch.Size([40])
 
※ 결과 해석
  • weight_ih_l0 : 입력 게이트, 망각 게이트, 셀 게이트, 출력 게이트의 가중치를 담당하는 입력-은닉 가중치 행렬입니다. 이 행렬은 각 게이트의 입력 부분에 대한 가중치를 포함하며, 이 경우 [40,4][40, 4]의 크기를 가집니다. 이 크기는 hidden_size 4배인 40 (hidden_size * 4)과 입력 특성의 수 4를 반영합니다.
  • weight_hh_l0 : 이전 타임 스텝의 은닉 상태에서 현재 타임 스텝의 은닉 상태로의 변환을 담당하는 은닉-은닉 가중치 행렬입니다. [40,10][40, 10] 크기는 은닉 상태의 크기 10에 4배를 곱한 값입니다.
  • bias_ih_l0 및 bias_hh_l0 : 각각 입력-은닉 가중치와 은닉-은닉 가중치에 대응하는 바이어스입니다. 각각의 크기는 [40][40]로, 모든 게이트에 대한 바이어스를 포함합니다.

 

4) 초기 은닉 상태 및 셀 상태 초기화

PyTorch에서 nn.LSTM 모듈은 은닉 상태를 [레이어의개수,배치의개수,은닉유닛의개수][레이어의 개수, 배치의 개수, 은닉 유닛의 개수]의 형태로 처리합니다.

이는 PyTorch의 약속된 표준 형태로, 모든 LSTM 구현에서 이 차원 구조를 따라야 합니다.

배치 크기를 명시적으로 다루지 않았지만, 여기서는 배치 크기를 1로 가정하여 모델을 처리하겠습니다.

이는 단일 시퀀스 또는 소규모 배치를 실행할 때 흔히 사용하는 설정입니다.

h0 = torch.zeros(1, 1, num_hidden)
c0 = torch.zeros(1, 1, num_hidden)

print("Hidden state shape:", h0.shape)
print("Cell state shape:", c0.shape)
Hidden state shape: torch.Size([1, 1, 10])
Cell state shape: torch.Size([1, 1, 10])

 

5) 시퀀스 데이터를 텐서로 변환

앞서 만들었던 시퀀스 데이터 (sequence_dataX)를 pytorch 텐서 sequence_data_tensor로 변환하여, 텐서 및 첫번째 시퀀스 형태를 출력합니다.

# 시퀀스 데이터를 텐서로 변환
sequence_data_tensor = torch.tensor(sequence_dataX, dtype=torch.float32)
print(f"sequence_dataX의 형태 : {sequence_dataX.shape}")
print(f"sequence_data_tensor의 형태 : {sequence_data_tensor.shape}")
print(f"sequence_data_tensor[0]의 형태 : {sequence_data_tensor[0].shape}")

display(sequence_data_tensor[0])

 

※ 결과 해석

sequence_dataX의 형태: (724, 6, 4)는 원본 데이터가 724개의 시퀀스를 갖고 있으며, 각 시퀀스는 6일 동안의 데이터, 그리고 각 일은 4개의 특성을 포함한다는 것을 나타냅니다.

sequence_data_tensor의 형태: torch.Size([724, 6, 4])로, 텐서 변환 후 형태가 동일하게 유지되었음을 보여줍니다. sequence_data_tensor[0]의 형태: torch.Size([6, 4])는 첫 번째 시퀀스가 6일 동안의 데이터를 각각 4개의 특성으로 포함하고 있음을 확인합니다.

첫 번째 시퀀스 sequence_data_tensor[0]는 LSTM 네트워크에 입력될 예정입니다.

각 시퀀스 데이터의 형태가 중요한 이유는, 나중에 배치 차원을 추가하는 과정(unsqueeze)을 통해 LSTM 네트워크의 입력 형태에 맞추어야 하기 때문입니다.

이는 모델이 데이터를 효과적으로 처리하고, 시간에 따른 패턴을 정확하게 학습할 수 있도록 합니다.

 

6) LSTM에 맞는 입력 형태로 시퀀스 데이터 변환

sequence_data_tensor[0]의 두번째 차원(차원 인덱스 1)에 대해 차원을 추가하여, nn.LSTM 인스턴스의 입력되는 Sequence 데이터의 형태(시퀀스 갯수, 배치 갯수, 피처 갯수 )로 맞춥니다.

batch_added_tensor = sequence_data_tensor[0].unsqueeze(1)
print(f"배치 차원 추가한 시퀀스 데이터 : {batch_added_tensor.shape}")
배치 차원 추가한 시퀀스 데이터 : torch.Size([6, 1, 4])

 

※ 결과 해석

NN.LSTM은 입력 데이터를 (시퀀스 개수, 배치 개수, 피처 개수)의 형태로 기대합니다.

만일 입력 데이터의 형태를 (배치 개수, 시퀀스 개수, 피처 개수)로 변경하고 싶다면, nn.LSTM 인스턴스 생성 시 batch_first 매개 변수를 True로 설정합니다.

기본 설정(default)은 (시퀀스 개수, 배치 개수, 피처 개수) 형태로 입력 데이터를 받는 것입니다.

unsqueeze(1) 함수를 통해 지정된 위치에 새로운 차원을 추가합니다.

이 경우, 첫 번째 시퀀스 데이터 sequence_data_tensor[0]에 배치 차원을 추가하여 LSTM 네트워크의 입력으로 사용할 수 있게 조정합니다.

원래 시퀀스의 형태가 [6, 4] (6일간의 데이터, 각 일에 4개의 특성)인데, unsqueeze(1)을 적용하면 [6, 1, 4] 형태로 변형됩니다.

이렇게 변경된 형태는 각 타임 스텝에서 단 하나의 데이터 포인트(배치 사이즈 1)가 있는 것과 같습니다.

 

7) LSTM 네트워크를 통한 시퀀스 처리

pytorch tensor로 변환한 시퀀스 데이터 sequence_data_tensor를, 앞에서 생성하였던 LSTM 네트워크 인스턴스인 model_lstm에 순차적으로 입력하여, 각 시퀀스에 대한 출력과 새로운 은닉 및 셀 상태를 얻어 보겠습니다.

tot_num_sequence_data = sequence_data_tensor.size(0)

for i in range(tot_num_sequence_data):
    # 현재 시퀀스 선택 및 차원 추가 (seq_len, batch, input_size)
    current_sequence = sequence_data_tensor[i].unsqueeze(1)  # 배치 차원 추가

    # LSTM 네트워크를 통한 시퀀스 처리
    output, (hn, cn) = model_lstm(current_sequence, (h0, c0))

 # 결과 출력 (첫 번째, 마지막 및 매 50번째 시퀀스만 출력)
    if i == 0 or i == sequence_data_tensor.size(0) - 1 or i % 100 == 0:
        print(f"Sequence {i+1} Output shape:", output.shape)
        print(f"Sequence {i+1} Hidden state shape:", hn.shape)
        print(f"Sequence {i+1} Cell state shape:", cn.shape)
        
    h0, c0 = hn, cn
Sequence 1 Output shape: torch.Size([6, 1, 10])
Sequence 1 Hidden state shape: torch.Size([1, 1, 10])
Sequence 1 Cell state shape: torch.Size([1, 1, 10])
Sequence 101 Output shape: torch.Size([6, 1, 10])
Sequence 101 Hidden state shape: torch.Size([1, 1, 10])
Sequence 101 Cell state shape: torch.Size([1, 1, 10])
Sequence 201 Output shape: torch.Size([6, 1, 10])
Sequence 201 Hidden state shape: torch.Size([1, 1, 10])
Sequence 201 Cell state shape: torch.Size([1, 1, 10])
Sequence 301 Output shape: torch.Size([6, 1, 10])
Sequence 301 Hidden state shape: torch.Size([1, 1, 10])
Sequence 301 Cell state shape: torch.Size([1, 1, 10])
Sequence 401 Output shape: torch.Size([6, 1, 10])
Sequence 401 Hidden state shape: torch.Size([1, 1, 10])
Sequence 401 Cell state shape: torch.Size([1, 1, 10])
Sequence 501 Output shape: torch.Size([6, 1, 10])
Sequence 501 Hidden state shape: torch.Size([1, 1, 10])
Sequence 501 Cell state shape: torch.Size([1, 1, 10])
Sequence 601 Output shape: torch.Size([6, 1, 10])
Sequence 601 Hidden state shape: torch.Size([1, 1, 10])
Sequence 601 Cell state shape: torch.Size([1, 1, 10])
Sequence 701 Output shape: torch.Size([6, 1, 10])
Sequence 701 Hidden state shape: torch.Size([1, 1, 10])
Sequence 701 Cell state shape: torch.Size([1, 1, 10])
Sequence 724 Output shape: torch.Size([6, 1, 10])
Sequence 724 Hidden state shape: torch.Size([1, 1, 10])
Sequence 724 Cell state shape: torch.Size([1, 1, 10])

 

8) TensorDataset과 DataLoader를 통한 배치 데이터 처리

 

※ TensorDataset과 DataLoader

TensorDataset
TensorDataset은 데이터와 그에 해당하는 레이블을 쉽게 다루기 위한 컨테이너입니다.

데이터와 레이블을 텐서(tensor) 형태로 묶어서 저장하고, 이 데이터 샘을 필요할 때 쉽게 꺼내 쓸 수 있게 해줍니다.

간단히 말해, TensorDataset은 데이터를 레이블과 함께 묶어서 관리하는 박스와 같습니다.

이를 통해 데이터를 처리하거나 모델에 전달할 때 일관성을 유지하고, 작업을 간소화할 수 있습니다.

 

DataLoader
DataLoader는 TensorDataset 같은 데이터셋을 받아서 모델 학습에 필요한 데이터 배치를 자동으로 준비해주는 도구입니다.

주요 사용되는 기능은 다음과 같습니다.

  • 배치 생성: 설정한 배치 크기(batch size)만큼 데이터를 여러 부분으로 나눕니다. 이렇게 하면 큰 데이터셋을 작은 부분으로 나누어 한 번에 하나의 배치만 메모리에 로드하여 처리할 수 있어 메모리 사용을 효율적으로 관리할 수 있습니다.
  • 셔플링(shuffling): 데이터를 무작위로 섞어서 모델이 학습하는 동안 데이터의 순서에 의존하지 않도록 합니다. 이는 모델이 일반화를 잘 할 수 있도록 돕는 중요한 과정입니다.
  • 멀티프로세싱: 데이터 로드 과정을 여러 프로세서에서 동시에 수행할 수 있도록 지원하여, 데이터 준비 시간을 줄이고 전체 학습 시간을 단축합니다.

※ TensorDataset과 DataLoader 사용 방법

  • 데이터 텐서화 : sequence_dataX와 sequence_dataY 배열을 torch.tensor를 사용하여 텐서로 변환합니다. dtype=torch.float32로 설정하여 부동소수점 연산을 위한 데이터 유형을 지정합니다.
  • TensorDataset 생성 : 변환된 텐서를 TensorDataset에 전달하여 데이터셋 객체를 생성합니다. 이 객체는 데이터와 레이블을 쌍으로 관리하며, 각 요소에 쉽게 접근할 수 있게 해줍니다.
  • DataLoader 설정 : DataLoader를 사용하여 train_dataset을 래핑하고, batch_size를 설정하여 미니배치 크기를 정의합니다. shuffle=True 옵션을 통해 에포크마다 데이터셋을 무작위로 섞어, 모델 학습 시 과적합을 방지하고 일반화 성능을 향상시킬 수 있습니다.
  • 배치 수 계산 : len(train_loader)를 통해 생성된 전체 배치 수를 계산합니다. 이는 전체 데이터 수를 배치 크기로 나눈 값과 같으며, 마지막 배치는 이보다 작을 수도 있습니다.
import torch
from torch.utils.data import TensorDataset, DataLoader

# 텐서로 변환된 시퀀스 데이터와 레이블
sequence_data_tensor = torch.tensor(sequence_dataX, dtype=torch.float32)
sequence_labels_tensor = torch.tensor(sequence_dataY, dtype=torch.float32)

# TensorDataset 생성
train_dataset = TensorDataset(sequence_data_tensor, sequence_labels_tensor)

# DataLoader 생성: 배치 크기를 정하고, 데이터 셋을 셔플
batch_size = 32  # 배치 크기 설정
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

total_num_batches = len(train_loader)
    
print("데이터셋 총 길이:", len(train_loader.dataset))
print("train_loader에 설정된 batch size:",train_loader.batch_size )  # 데이터셋의 총 샘플 수
print("num total batches in train_loader:",total_num_batches)   # 데이터셋의 총 샘플 

# 첫 번째 배치를 불러와서 데이터 형태 확인
first_batch = next(iter(train_loader))
data, target = first_batch
print(f"첫번째 배치 데이터 'data'의 형태 : {data.shape}")
print(f"첫번째 배치 데이터 'target' 형태 : {target.shape}")
데이터셋 총 길이: 724
train_loader에 설정된 batch size: 32
num total batches in train_loader: 23
첫번째 배치 데이터 'data'의 형태 : torch.Size([32, 6, 4])
첫번째 배치 데이터 'target' 형태 : torch.Size([32])

 

※ 결과 해석

len(train_loader.dataset)
train_loader.dataset의 전체 길이, 즉 데이터셋에 있는 총 데이터 샘플 수를 나타냅니다. 724개의 데이터 샘플이 있음을 알 수 있으며, 이는 모델이 학습 과정에서 사용할 전체 데이터의 양을 의미합니다.

 

train_loader.batch_size
DataLoader가 설정된 배치 크기를 나타냅니다. 여기서 배치 크기가 32라는 것은, DataLoader가 데이터셋에서 한 번에 32개의 데이터 샘플을 로드하여 모델에 전달하도록 구성되어 있음을 의미합니다.

 

len(train_loader)
전체 데이터셋을 위에서 설정한 배치 크기로 나누었을 때 생성되는 총 배치의 수를 나타냅니다. 즉, 724개의 데이터 샘플을 32개씩 묶으면 총 23개의 배치가 만들어진다는 것을 의미합니다. 마지막 배치는 32개보다 작은 수의 샘플을 포함할 수 있습니다.

PyTorch의 DataLoader에서 제공하는 drop_last 옵션은 데이터 로딩 과정에서 마지막 배치의 크기가 다른 배치보다 작을 때 이를 사용할지 여부를 결정하는 설정입니다. 이 옵션을 사용하면 데이터셋을 배치 크기로 나누었을 때 나머지 샘플을 포함하는 마지막 배치를 버릴 수 있습니다.

 

first_batch = next(iter(train_loader))
여기서 iter(train_loader)는 train_loader로부터 이터레이터를 생성합니다. DataLoader 객체는 파이썬의 이터레이터 프로토콜을 지원하므로, iter() 함수를 사용하여 이터레이터를 얻을 수 있습니다. next() 함수를 사용하면 이터레이터에서 다음 요소, 즉 첫 번째 데이터를 가져옵니다. 이 배치는 데이터와 레이블을 포함하는 튜플입니다.

 

data, target = first_batch
first_batch는 데이터와 타겟(레이블)을 포함하는 튜플입니다. 이 코드 라인은 튜플의 두 요소를 data와 target 변수로 언패킹합니다. data는 모델에 입력될 특성을 포함하며, target은 해당 데이터의 레이블입니다.

 

9) 연속적 시퀀스 데이터를 배치 단위로 처리하고 LSTM으로 결과 출력하기

model_lstm = nn.LSTM(input_size=num_features, hidden_size=num_hidden, num_layers=1)

i=0
# 데이터 로더를 이용하여 배치 데이터 처리
for data, target in train_loader:
    # 동적으로 h0, c0 초기화
    batch_size_actual = data.size(0)  # 실제 배치 크기
    
    data = data.permute(1, 0, 2)
    
    h0 = torch.zeros(1, batch_size_actual, num_hidden)
    c0 = torch.zeros(1, batch_size_actual, num_hidden)

    # LSTM 네트워크를 통한 시퀀스 처리
    output, (hn, cn) = model_lstm(data, (h0, c0))
    
    if i== (total_num_batches-1) or i== (total_num_batches-2) or i== (total_num_batches-3):
        print(f"{i+1}th Batch data shape:{data.shape}")  # 각 배치의 데이터 형태
        print(f"{i+1}th Batch target shape: {target.shape}")  # 각 배치의 타겟 형태
        print(f"{i+1}th Output shape of batch: {output.shape}")  # 모델 출력 형태

    i += 1
21th Batch data shape:torch.Size([6, 32, 4])
21th Batch target shape: torch.Size([32])
21th Output shape of batch: torch.Size([6, 32, 10])
22th Batch data shape:torch.Size([6, 32, 4])
22th Batch target shape: torch.Size([32])
22th Output shape of batch: torch.Size([6, 32, 10])
23th Batch data shape:torch.Size([6, 20, 4])
23th Batch target shape: torch.Size([20])
23th Output shape of batch: torch.Size([6, 20, 10])

'딥러닝 > 딥러닝: 시계열 데이터' 카테고리의 다른 글

LSTM 종합 코드 정리  (0) 2025.01.28
LSTM 학습과 추론, 모델 저장과 복원  (0) 2025.01.24
LSTM 원리와 구조 및 LSTMcell 구현  (0) 2025.01.23
RNN 구현  (0) 2025.01.22
RNN 원리와 구조  (0) 2025.01.22