Keras LSTM พร้อมอนุกรมเวลา 1D


10

ฉันเรียนรู้วิธีการใช้ Keras และผมเคยประสบความสำเร็จที่เหมาะสมกับชุดที่มีป้ายกำกับของฉันโดยใช้ตัวอย่างใน Chollet ของการเรียนรู้ลึกหลาม ชุดข้อมูลคือ ~ 1000 Time Series ที่มีความยาว 3125 กับ 3 คลาสที่อาจเกิดขึ้น

ฉันต้องการไปไกลกว่าเลเยอร์หนาแน่นพื้นฐานซึ่งให้อัตราการคาดคะเนประมาณ 70% และหนังสือเล่มนี้จะพูดถึงเลเยอร์ LSTM และ RNN

ตัวอย่างทั้งหมดดูเหมือนจะใช้ชุดข้อมูลที่มีคุณสมบัติหลายอย่างสำหรับแต่ละชุดเวลาและฉันพยายามหาวิธีนำข้อมูลมาใช้ให้เกิดประโยชน์

ตัวอย่างเช่นฉันมี 1000x3125 Time Series ฉันจะป้อนสิ่งนั้นลงในเลเยอร์ 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 แถวและ 1,000 คอลัมน์โดยที่แต่ละแถวเป็นขั้นตอนเดียว ตัวแปรเป้าหมายควรมี 3125 แถวและ 1 คอลัมน์โดยที่แต่ละค่าสามารถเป็นหนึ่งในสามค่าที่เป็นไปได้ ดูเหมือนว่าคุณกำลังประสบปัญหาการจำแนกประเภท ในการตรวจสอบในรหัสฉันจะทำ:

>>> X.shape
(3125, 1000)

>>> y.shape
(1000,)

คลาส LSTM ต้องการให้แต่ละตัวอย่างเดียวประกอบด้วยเวลา 'บล็อก' สมมติว่าคุณต้องการบล็อก 100 ขั้นตอน วิธีการนี้คือตัวอย่างการป้อนข้อมูลเดียวซึ่งสอดคล้องกับตัวแปรเป้าหมายที่X[0:100] y[100]นี้หมายถึงขนาดของหน้าต่างของคุณ (aka จำนวนเวลาขั้นตอนหรือจำนวนของล่าช้า) เท่ากับ 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 หลายคน ( 'ซ้อน' พวกเขา) แล้วคุณจะต้องเพิ่มการโต้แย้งอีกหนึ่งทั้งหมด แต่สุดท้าย คือการLSTMreturn_sequences=True


ขอบคุณสำหรับคำตอบที่ครอบคลุม Dexter (!) เกี่ยวกับความคิดเห็นของคุณเกี่ยวกับขนาดของชุดงาน batch_size มีการระบุไว้ใน model.fit อาร์กิวเมนต์พารามิเตอร์ที่แตกต่างกันเมื่อเทียบกับการสร้างชุดที่กำหนดเองของฉัน? ฉันจัดการเพื่อให้โค้ดของฉันทำงานอย่างน้อยโดยเปลี่ยนรูปร่างข้อมูลของฉันจากเมทริกซ์ 1000x3125 เป็นเมทริกซ์ 3D โดยใช้ data = np.reshape (data, (1,000,1,3125)) นี่ให้ฉันรัน LSTM ด้วย input_shape (1,3125) แต่อีกครั้งฉันไม่แน่ใจว่าฉันกำลังทำอะไรอยู่ อีกครั้งขอบคุณมากสำหรับคำตอบ ฉันจะดูลิงค์ที่คุณให้และศึกษาคำตอบของคุณเพิ่มเติม
user1147964

ยินดีต้อนรับคุณ! ใช่คุณได้มันถ้าคุณปล่อยออกมาเมื่อกำหนดรูปแบบที่มันจะถูกนำมาจากอาร์กิวเมนต์เดียวกันภายในbatch_size model.fit()คุณควรปรับรูปแบบที่จะได้รับ(3025, 100, 1000)ซึ่งหมายถึง 3025 แบทช์แต่ละ 100 (แถว) เวลาและตัวแปร 1,000 (คอลัมน์) การใช้งานnp.reshapeจะไม่ทำงานสำหรับเรื่องนี้ (คุณจะได้รับข้อผิดพลาด) เนื่องจากความจริงที่ว่าคุณจะมีข้อมูลทับซ้อน ... รูปร่างสุดท้ายมีข้อมูลมากกว่าอินพุต 3025x100x1000> 3125x1000 - np.reshapeไม่ชอบเพราะมันคลุมเครือ ฉันขอแนะนำให้วนลูปมากกว่าชุดข้อมูล 1 ตัวอย่าง = 1 ตัวอย่าง
n1k31t4

ฉันคิดว่าฉันสับสนเล็กน้อยที่นี่และอาจเป็นเพราะฉันอาจทำกระบวนการแบทช์โดยไม่ได้ตั้งใจฉันจะใช้ค่าเฉพาะที่นี่ ฉันสุ่มตัวอย่าง 3 การวัดต่าง ๆ ที่ 6.25 kHz เป็นเวลาประมาณ 3 นาทีส่งผลให้มีความยาวอนุกรม 3 เท่า 1093750 สิ่งนี้สร้างเมทริกซ์ 3x1093750 จากนั้นฉันแบ่งส่วน TS แต่ละอันออกเป็น 0.5 วินาทีทำให้เกิดเมทริกซ์ 1050x3125 ฉันสามารถปรับโครงสร้างนี้เป็นเมทริกซ์สามมิติด้วยขนาด 3x350x3125 สิ่งนี้ทำให้ฉันมี "แบตช์" ยาว 350, 0.5 วินาที ดูเหมือนว่าการก่อร่างใหม่ของคุณจะสร้างคุณค่ามากขึ้นขอบคุณสำหรับการตอบกลับอีกครั้ง ขออภัย
user1147964

เพียงเพิ่มการอ่านลิงก์แรกที่คุณโพสต์ทำให้ฉันคิดว่าฉันกำลังปรับแต่งสิ่งต่าง ๆ อย่างถูกต้อง ขอโทษถ้าฉันขาดอะไรบางอย่างที่เห็นได้ชัด แต่ที่นี่พวกเขาเริ่มต้นด้วยความยาว TS 5000 และกลายเป็นเมทริกซ์สามมิติด้วยมิติ [1 25 200]
user1147964

เมื่อเทียบกับวิธีการในลิงค์ของคุณฉันจะสร้างตัวอย่างอีกมากมาย นี่เป็นเพราะฉันใช้หน้าต่าง 'กลิ้ง' ชนิดหนึ่ง ดูภาพนี้ พวกเขาไม่ได้ใช้หน้าต่างกลิ้ง การทำ 3 นาทีเป็น 350x0.5s ชิ้นนั้นก็โอเค (อาจไม่จำเป็น - คุณคาดเดาบ่อยแค่ไหน) แต่ละอันควร 3x3125 "ฉันสามารถปรับโครงสร้างนี้เป็นเมทริกซ์สามมิติด้วยขนาด 3x350x3125" - ฟังดูดีขึ้น แต่หลังจากทำการแยกฉันคาดหวังว่า 350x3x3125 (350 ชิ้นของ 3x3125) แต่ละชิ้นเหล่านี้สามารถดำเนินการตามที่ฉันอธิบาย
n1k31t4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.