1D zaman serisiyle Keras LSTM


10

Keras'ı nasıl kullanacağımı öğreniyorum ve Chollet'in Python için Deep Learning'deki örneklerini kullanarak etiketli veri setimle makul bir başarı elde ettim . Veri seti 3 potansiyel sınıflı 3125 uzunluğunda ~ 1000 Zaman Serisidir.

Bana yaklaşık% 70 tahmin oranı veren temel Yoğun katmanların ötesine geçmek istiyorum ve kitap LSTM ve RNN katmanlarını tartışmaya devam ediyor.

Tüm örnekler, her zaman dizisi için birden çok özelliğe sahip veri kümeleri kullanıyor gibi görünüyor ve sonuç olarak verilerimi nasıl uygulayacağımı çözmek için uğraşıyorum.

Örneğin, 1000x3125 Zaman Serim varsa, bunu SimpleRNN veya LSTM katmanı gibi bir şeyle nasıl beslerim? Bu katmanların ne yaptığına dair bazı temel bilgileri kaçırıyor muyum?

Mevcut kod:

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()

Yanıtlar:


10

LSTM katmanları farklı bir şekle sahip veriler gerektirir.

Açıklamanızdan, başlangıç ​​veri kümesinin, her satırın bir zaman adımı olduğu 3125 satır ve 1000 sütuna sahip olduğunu anlıyorum. Hedef değişken daha sonra 3125 satır ve 1 sütuna sahip olmalıdır, burada her değer üç olası değerden biri olabilir. Yani bir sınıflandırma sorunu yapıyormuşsunuz gibi geliyor. Bu kodu kontrol etmek için yapardı:

>>> X.shape
(3125, 1000)

>>> y.shape
(1000,)

LSTM sınıfı, her bir örneğin bir 'blok' zaman diliminden oluşmasını gerektirir. Diyelim ki 100 adımlık bir blok almak istiyorsunuz. Bu X[0:100], adresindeki hedef değişkene karşılık gelen tek bir giriş örneğidir y[100]. bu pencere boyutunuzun (diğer adıyla zaman adımı sayısı veya gecikme sayısı) 100'e eşit olduğu anlamına gelir. Yukarıda belirtildiği gibi 3125 örneğiniz var, yani N = 3125. İlk bloğu oluşturmak için maalesef y, mevcut verilerden 100'lük bir blok oluşturamayacağımızdan ilk 100 örneğini atmamız gerekiyor (daha önce veri noktalarına ihtiyacımız olacaktı X[0]).

Tüm bunlar göz önüne alındığında, bir LSTM, == (N - window_size, window_size, num_features)anlamına gelen şekil yığınları teslim etmenizi gerektirir .(3125 - 100, 100, 1000)(3025, 100, 1000)

Bu zaman bloklarını oluşturmak biraz zordur, ancak bir kez iyi bir işlev oluşturun, ardından kaydedin :)

Yapılacak daha çok iş var, belki yukarıda benim açıklama derinliği örneklerde daha bakmak buraya ... ya bir okuma var LSTM belgelerinde (hala iyi ya, kaynak kodu! ).

Son model (kodunuza göre) yeterince basit olacaktır:

#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'])

Modelin giriş şekli ile ilgili belgelereSequential göz atın . Temel olarak, içindeki parti sayısını belirtmemize gerek olmadığını söylüyor input_shape. Örneğin batch_size=50, sabit bir sayı olmasını gerektiriyorsa yapılabilir.

input_shapeArgümanın dokümantasyonda olmadığını biliyorum LSTM, ancak sınıfın kendisi miras alır RNN, bu da miras alır Layer- böylece sağladığınız bilgileri kullanabilirsiniz.

Son bir ipucu: Birden LSTM katmanları ekleyerek planlıyorsanız (onları 'istifleme'), o zaman tüm ama bir daha argüman eklemem gerekiyor edecektir geçen LSTM , yani return_sequences=True.


Kapsamlı cevap Dexter (!) İçin teşekkürler. Toplu iş boyutu hakkındaki yorumlarınızla ilgili olarak, model.fit argümanında batch_size, kendi özel toplu işimi yapmama kıyasla farklı bir hiper parametre mi? Kodumu en azından data = np.reshape (data, (1000,1,3125)) kullanarak bir 1000x3125 matrisinden bir 3D matrise yeniden şekillendirerek çalıştırmayı başardım. Bu, LSTM'yi input_shape (1,3125) ile çalıştırmama izin veriyor, ancak yine de ne yaptığımdan emin değilim. Tekrar, cevap için çok teşekkür ederim. Verdiğiniz bağlantılara bir göz atacağım ve cevabınızı biraz daha inceleyeceğim.
user1147964

Rica ederim! Evet, batch_sizeanladınız, modeli tanımlarken dışarıda kalırsanız , aynı argümandan alınacaktır model.fit(). Almak için yeniden şekillendirmelisiniz (3025, 100, 1000), yani 3025 toplu iş, 100 (satır) zaman atımı ve 1000 (sütun) değişkenin her biri. Kullanmak np.reshapene yazık ki bunun için işe yaramaz (bir hata alırsınız), çünkü veri çakışmaları olacak ... son şeklin girişten daha fazla veri var. 3025x100x1000> 3125x1000 - np.reshapebelirsiz olduğu için hoşlanmıyor. Sadece veri kümesi üzerinde döngü, 1 döngü = 1 örnek öneririz.
n1k31t4

Sanırım burada biraz kafam karıştı ve bunun nedeni, kazayla toplu işlemi zaten yapmış olabileceğim olabilir. Burada belirli değerler kullanacağım. 3 kez yaklaşık 5 dakika boyunca 6.25 kHz'de 3 farklı ölçüm örnekledim, bu da 3 zaman serisi 1093750 ile sonuçlandı. Bu bir 3x1093750 matrisi oluşturur. Daha sonra her bir TS'yi 0,5 saniyelik artışlarla segmentlere ayırdım, bu da 1050x3125'lik bir matrise neden oldu. Bunu teknik olarak 3x350x3125 boyutlarında bir 3D matris olarak yeniden yapılandırabilirim. Bu bana 350, 0.5s uzunluğunda "gruplar" verir. Yeniden şekillendirmeniz çok daha fazla değer üretiyor gibi görünüyor Tekrar yanıt için teşekkürler. Üzgünüz
user1147964

Sadece eklemek için, gönderdiğiniz ilk bağlantıyı okumak, işleri doğru bir şekilde yeniden şekillendirdiğimi düşündürüyor. Eğer açık bir şeyi özlüyorsam özür dilerim ama burada TS uzunluğu 5000 ile başlıyorlar ve boyutları ile bir 3D matrise dönüştürüyorlar [1 25 200].
user1147964

Bağlantınızdaki yönteme kıyasla, yolum çok daha fazla örnek oluşturacak. Çünkü bir tür 'yuvarlanan' pencere kullanıyorum. Bu tasvire bir göz atın . Hareketli pencere kullanmazlar . 350x0.5s parçalarına 3 dakika yapmak tamamdır (belki de gerekli değildir - ne sıklıkla tahmin edersiniz?), Her parça 3x3125 olmalıdır. "Bunu 3x350x3125 boyutlarında bir 3D matris olarak yeniden yapılandırabilirim - bu daha iyi geliyor, ancak bölünmeleri yaptıktan sonra 350x3x3125 (350 x 3x3125 parça) beklerdim. Bu parçaların her biri daha sonra tarif ettiğim gibi işlenebilir.
n1k31t4
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.