1D 시계열이있는 Keras LSTM


10

Keras 사용법을 배우고 있으며 Chollet 's Deep Learning for Python 의 예제를 사용하여 레이블이 지정된 데이터 세트로 합리적인 성공을 거두었습니다 . 데이터 세트는 3 개의 잠재적 클래스를 가진 길이가 3125 인 ~ 1000 시계열입니다.

70 %의 예측률을 제공 하는 기본 Dense 레이어를 넘어서서이 책에서 LSTM 및 RNN 레이어에 대해 논의하려고합니다.

모든 예제는 각 시계열마다 여러 기능이있는 데이터 세트를 사용하는 것으로 보이며 결과적으로 데이터를 구현하는 방법을 연구하기 위해 고심하고 있습니다.

예를 들어, 1000x3125 시계열이있는 경우 SimpleRNN 또는 LSTM 레이어와 같은 방식으로 어떻게 피드합니까? 이 레이어의 기능에 대한 기본 지식이 누락 되었습니까?

현재 코드 :

import pandas as pd
import numpy as np
import os
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM, Dropout, SimpleRNN, Embedding, Reshape
from keras.utils import to_categorical
from keras import regularizers
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

def readData():
    # Get labels from the labels.txt file
    labels = pd.read_csv('labels.txt', header = None)
    labels = labels.values
    labels = labels-1
    print('One Hot Encoding Data...')
    labels = to_categorical(labels)

    data = pd.read_csv('ts.txt', header = None)

    return data, labels

print('Reading data...')
data, labels = readData()

print('Splitting Data')
data_train, data_test, labels_train, labels_test = train_test_split(data, labels)

print('Building Model...')
#Create model
model = Sequential()
## LSTM / RNN goes here ##
model.add(Dense(3, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

print('Training NN...')
history = model.fit(data_train, labels_train, epochs=1000, batch_size=50,
    validation_split=0.25,verbose=2)

results = model.evaluate(data_test, labels_test)

predictions = model.predict(data_test)

print(predictions[0].shape)
print(np.sum(predictions[0]))
print(np.argmax(predictions[0]))

print(results)

acc = history.history['acc']
val_acc = history.history['val_acc']
epochs = range(1, len(acc) + 1)

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

답변:


10

LSTM 레이어에는 다른 모양의 데이터가 필요합니다.

귀하의 설명에서 시작 데이터 세트에는 3125 개의 행과 1000 개의 열이 있으며 각 행은 한 번의 단계입니다. 대상 변수는 3125 개의 행과 1 개의 열을 가져야하며, 각 값은 가능한 3 가지 값 중 하나 일 수 있습니다. 분류 문제를 겪고있는 것처럼 들립니다. 이것을 코드에서 확인하려면 다음을 수행하십시오.

>>> X.shape
(3125, 1000)

>>> y.shape
(1000,)

LSTM 클래스는 각 단일 샘플이 '블록'시간으로 구성되어야합니다. 100 개의 타임 스텝 블록을 원한다고 가정 해 봅시다. 이는 X[0:100]단일 입력 샘플이며 이는의 목표 변수에 해당합니다 y[100]. 이것은 창 크기 (일명 시간 단계 또는 지연 수)가 100과 같다는 것을 의미합니다. 위에서 언급 한 것처럼 3125 개의 샘플이 N = 3125있습니다. 첫 번째 블록을 만들려면 불행히도의 첫 100 개 샘플을 버려야합니다 y. 사용 가능한 데이터에서 100 개의 전체 블록을 만들 수 없기 때문입니다 (우리는 이전에 데이터 포인트가 필요합니다 X[0]).

이 모든 것을 감안할 때 LSTM은 배치 모양을 제공해야하므로 == (N - window_size, window_size, num_features)로 변환됩니다 .(3125 - 100, 100, 1000)(3025, 100, 1000)

이러한 타임 블록을 만드는 것은 번거롭지 만 좋은 기능을 한 번 만든 다음 저장하십시오. :)

더 많은 작업이 필요합니다. 여기서 위의 설명에 대한 더 자세한 예를 보거나 LSTM 설명서 (또는 더 나은 소스 코드! )를 읽으십시오 .

최종 모델은 다음과 같이 간단합니다 (코드 기준).

#Create model
model = Sequential()
model.add(LSTM(units=32, activation='relu',
               input_shape=(100, 1000))    # the batch size is neglected!
model.add(Dense(3, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam',
              metrics=['accuracy'])

모델의 입력 형태에 관한 문서를Sequential 살펴보십시오 . 기본적으로에 배치 수를 지정할 필요가 없다고 말합니다 input_shape. batch_size=50고정 번호가 필요한 경우 예를 들어으로 수행 할 수 있습니다 .

나는 알고 input_shape인수에 대한 설명서에없는 LSTM,하지만 클래스 자체에서 상속 RNN, 어떤에서 차례 상속에 Layer- 당신이 제공하는 정보를 사용할 수 있도록.

마지막 팁 : 여러 LSTM 레이어를 추가 ( '스태킹')하려는 경우 마지막 을 제외한 모든 인수 ( LSTM즉,) 에 하나 이상의 인수를 추가해야 합니다 return_sequences=True.


포괄적 인 답변 Dexter (!)에 감사드립니다. 배치 크기에 대한 귀하의 의견과 관련하여 model.fit 인수에 지정된 batch_size가 내 사용자 정의 배치를 만드는 것과 비교하여 다른 하이퍼 매개 변수입니까? data = np.reshape (data, (1000,1,3125))를 사용하여 1000x3125 매트릭스에서 3D 매트릭스로 데이터를 재구성하여 코드를 실행하는 데 성공했습니다. 이를 통해 input_shape (1,3125)를 사용하여 LSTM을 실행할 수 있었지만 다시 한 번 내가 무엇을하고 있는지 잘 모르겠습니다. 답장을 보내 주셔서 다시 한 번 감사드립니다. 제공 한 링크를 살펴보고 답변을 좀 더 공부하겠습니다.
user1147964

천만에요! 그렇습니다 batch_size. 모델을 정의 할 때 제외 하면 모델 내의 동일한 인수에서 가져옵니다 model.fit(). get으로 재구성해야합니다. (3025, 100, 1000)즉, 각각 100 (행) 타임 스텝 및 1000 (열) 변수 인 3025 개의 배치를 의미합니다. np.reshape데이터가 겹칠 것이라는 사실 때문에 사용 하면 슬프게도 작동하지 않습니다 (오류가 발생합니다). 최종 모양에는 입력보다 많은 데이터가 있습니다. 3025x100x1000> 3125x1000 - np.reshape하지 않습니다이 모호한으로 그런. 단순히 데이터 세트, 1 루프 = 1 샘플을 반복하는 것이 좋습니다.
n1k31t4

나는 여기에 약간 혼란스러워 생각하고 실수로 이미 일괄 처리 프로세스를 수행했을 수 있기 때문에 여기에서 특정 값을 사용합니다. 약 3 분 동안 6.25kHz에서 3 가지 측정을 샘플링하여 길이가 1093750 인 3 개의 시계열을 생성했습니다. 이렇게하면 3x1093750 매트릭스가 생성됩니다. 그런 다음 각 TS를 0.5 초 단위로 분할하여 1050x3125 매트릭스를 생성했습니다. 기술적으로 3x350x3125 크기의 3D 매트릭스로 구조를 재구성 할 수 있습니다. 이것은 350, 0.5 초 길이의 "배치"를 제공합니다. 재구성 한 결과 더 많은 값을 생성하는 것 같습니다. 다시 응답 해 주셔서 감사합니다. 죄송합니다
user1147964

덧붙여서, 당신이 게시 한 첫 번째 링크를 읽으면 내가 물건을 올바르게 재구성한다고 생각합니다. 내가 명백한 것을 놓치고 있다면 사과하지만 여기서는 TS 길이 5000으로 시작하여 치수가 [1 25 200] 인 3D 행렬로 바꾼다.
user1147964

귀하의 링크의 방법과 비교할 때 내 방법은 더 많은 샘플을 생성합니다. 이것은 일종의 '롤링'창을 사용하고 있기 때문입니다. 한 번 봐 가지고 이 묘사 . 롤링 창을 사용하지 않습니다 . 3 분을 350x0.5s 청크로 만들면 괜찮습니다 (필요하지는 않지만 얼마나 자주 예측합니까?). 각 청크는 3x3125 여야합니다. "크기를 3x350x3125 인 3D 매트릭스로 재구성 할 수 있습니다." -소리가 나아지지만 분할 후 350x3x3125 (3x3125의 350 청크)가 필요합니다. 이 청크 각각은 내가 설명한대로 처리 될 수 있습니다.
n1k31t4
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.