Saya mencoba mendamaikan pemahaman saya tentang LSTM dan ditunjukkan di sini di posting ini oleh Christopher Olah diimplementasikan di Keras. Saya mengikuti blog yang ditulis oleh Jason Brownlee untuk tutorial Keras. Yang paling membuat saya bingung adalah,
- Pembentukan kembali seri data menjadi
[samples, time steps, features]
dan, - LSTM stateful
Mari kita berkonsentrasi pada dua pertanyaan di atas dengan mengacu pada kode yang ditempel di bawah ini:
# reshape into X=t and Y=t+1
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 1))
testX = numpy.reshape(testX, (testX.shape[0], look_back, 1))
########################
# The IMPORTANT BIT
##########################
# create and fit the LSTM network
batch_size = 1
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
for i in range(100):
model.fit(trainX, trainY, nb_epoch=1, batch_size=batch_size, verbose=2, shuffle=False)
model.reset_states()
Catatan: create_dataset mengambil urutan panjang N dan mengembalikan N-look_back
array yang masing-masing elemen adalah look_back
urutan panjang.
Apa itu Langkah dan Fitur Waktu?
Seperti dapat dilihat TrainX adalah array 3-D dengan Time_steps dan Fitur menjadi dua dimensi terakhir masing-masing (3 dan 1 dalam kode khusus ini). Sehubungan dengan gambar di bawah, apakah ini berarti bahwa kami sedang mempertimbangkan many to one
kasus ini, di mana jumlah kotak merah muda adalah 3? Atau apakah secara harfiah berarti panjang rantai adalah 3 (yaitu hanya 3 kotak hijau yang dipertimbangkan).
Apakah argumen fitur menjadi relevan ketika kita mempertimbangkan seri multivarian? mis. memodelkan dua saham finansial secara bersamaan?
LSTM Stateful
Apakah LSTMs stateful berarti bahwa kita menyimpan nilai memori sel antara sejumlah batch? Jika ini masalahnya, batch_size
adalah satu, dan memori diatur ulang di antara latihan yang berjalan, jadi apa gunanya mengatakan bahwa itu stateful. Saya menduga ini terkait dengan fakta bahwa data pelatihan tidak dikocok, tapi saya tidak yakin bagaimana caranya.
Adakah pikiran? Referensi gambar: http://karpathy.github.io/2015/05/21/rnn-effectiveness/
Edit 1:
Agak bingung tentang komentar @ van tentang kotak merah dan hijau yang sama. Jadi hanya untuk mengonfirmasi, apakah panggilan API berikut sesuai dengan diagram yang belum dibuka? Terutama mencatat diagram kedua ( batch_size
dipilih secara sewenang-wenang.):
Edit 2:
Untuk orang-orang yang telah melakukan kursus pembelajaran mendalam Udacity dan masih bingung tentang argumen time_step, lihat diskusi berikut: https://discussions.udacity.com/t/rnn-lstm-use-implementation/163169
Memperbarui:
Ternyata model.add(TimeDistributed(Dense(vocab_len)))
apa yang saya cari. Berikut ini sebuah contoh: https://github.com/sachinruk/ShakespeareBot
Pembaruan2:
Saya telah merangkum sebagian besar pemahaman saya tentang LSTM di sini: https://www.youtube.com/watch?v=ywinX5wgdEU
sumber
Jawaban:
Pertama-tama, Anda memilih tutorial yang bagus ( 1 , 2 ) untuk memulai.
Apa Time-step artinya :
Time-steps==3
dalam X.shape (Menjelaskan bentuk data) berarti ada tiga kotak merah muda. Karena dalam Keras setiap langkah memerlukan input, oleh karena itu jumlah kotak hijau biasanya harus sama dengan jumlah kotak merah. Kecuali Anda meretas struktur.banyak ke banyak vs banyak ke satu : Di keras, ada
return_sequences
parameter saat Anda menginisialisasiLSTM
atauGRU
atauSimpleRNN
. Ketikareturn_sequences
adalahFalse
(secara default), maka itu adalah banyak untuk satu seperti yang ditunjukkan pada gambar. Bentuk kembalinya adalah(batch_size, hidden_unit_length)
, yang mewakili kondisi terakhir. Ketikareturn_sequences
iniTrue
, maka banyak ke banyak . Bentuk kembalinya adalah(batch_size, time_step, hidden_unit_length)
Apakah argumen fitur menjadi relevan : Argumen fitur berarti "Seberapa besar kotak merah Anda" atau berapa dimensi input setiap langkah. Jika Anda ingin memprediksi dari, katakanlah, 8 jenis informasi pasar, maka Anda dapat menghasilkan data Anda
feature==8
.Stateful : Anda dapat mencari kode sumber . Ketika menginisialisasi keadaan, jika
stateful==True
, maka keadaan dari pelatihan terakhir akan digunakan sebagai keadaan awal, jika tidak maka akan menghasilkan keadaan baru. Saya belum nyalakanstateful
. Namun, saya tidak setuju dengan itubatch_size
hanya bisa 1 kapanstateful==True
.Saat ini, Anda menghasilkan data Anda dengan data yang dikumpulkan. Gambar informasi stok Anda datang sebagai aliran, daripada menunggu satu hari untuk mengumpulkan semua berurutan, Anda ingin menghasilkan data input online saat pelatihan / prediksi dengan jaringan. Jika Anda memiliki 400 saham yang berbagi jaringan yang sama, maka Anda dapat mengatur
batch_size==400
.sumber
stateful: Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
lookback = 1
?stateful=True
: Ukuran bets bisa apa saja yang Anda suka, tetapi Anda harus menaatinya. Jika Anda membangun model Anda dengan ukuran 5, maka semuafit()
,predict()
dan metode terkait akan membutuhkan 5. Namun perlu dicatat bahwa keadaan ini tidak akan disimpanmodel.save()
, yang mungkin tampak tidak diinginkan. Namun Anda dapat secara manual menambahkan status ke file hdf5, jika Anda memerlukannya. Tetapi secara efektif ini memungkinkan Anda untuk mengubah ukuran batch hanya dengan menyimpan dan memuat ulang model.Sebagai pelengkap jawaban yang diterima, jawaban ini menunjukkan perilaku keras dan cara mencapai setiap gambar.
Perilaku keras umum
Pemrosesan internal keras standar selalu banyak ke banyak seperti pada gambar berikut (di mana saya menggunakan
features=2
, tekanan dan suhu, hanya sebagai contoh):Dalam gambar ini, saya meningkatkan jumlah langkah menjadi 5, untuk menghindari kebingungan dengan dimensi lain.
Untuk contoh ini:
Array input kami kemudian harus berbentuk seperti
(N,5,2)
:Input untuk jendela geser
Seringkali, lapisan LSTM seharusnya memproses seluruh urutan. Membagi windows mungkin bukan ide terbaik. Lapisan memiliki keadaan internal tentang bagaimana suatu urutan berkembang ketika ia melangkah maju. Windows menghilangkan kemungkinan mempelajari urutan panjang, membatasi semua urutan ke ukuran jendela.
Di windows, setiap jendela adalah bagian dari urutan asli yang panjang, tetapi oleh Keras mereka akan dilihat masing-masing sebagai urutan independen:
Perhatikan bahwa dalam kasus ini, Anda awalnya hanya memiliki satu urutan, tetapi Anda membaginya dalam banyak urutan untuk membuat windows.
Konsep "apa itu urutan" adalah abstrak. Bagian penting adalah:
Mencapai setiap kasus dengan "lapisan tunggal"
Mencapai standar banyak ke banyak:
Anda dapat mencapai banyak ke banyak dengan lapisan LSTM sederhana, menggunakan
return_sequences=True
:Mencapai banyak orang menjadi satu:
Dengan menggunakan layer yang sama persis, keras akan melakukan preprocessing internal yang sama persis, tetapi ketika Anda menggunakan
return_sequences=False
(atau mengabaikan argumen ini), keras akan secara otomatis membuang langkah-langkah sebelum yang terakhir:Mencapai satu ke banyak
Sekarang, ini tidak didukung oleh lapisan LSTM yang keras saja. Anda harus membuat strategi sendiri untuk melipatgandakan langkah-langkahnya. Ada dua pendekatan yang baik:
stateful=True
untuk secara berulang mengambil output dari satu langkah dan menyajikannya sebagai input dari langkah berikutnya (kebutuhanoutput_features == input_features
)Satu ke banyak dengan vektor berulang
Agar sesuai dengan perilaku standar yang keras, kita membutuhkan input dalam langkah-langkah, jadi, kita cukup mengulangi input untuk panjang yang kita inginkan:
Memahami stateful = Benar
Kini hadir salah satu kemungkinan penggunaan
stateful=True
(selain menghindari pemuatan data yang tidak dapat memuat memori komputer Anda sekaligus)Stateful memungkinkan kita untuk memasukkan "bagian" dari urutan secara bertahap. Perbedaannya adalah:
stateful=False
, batch kedua berisi urutan baru, terlepas dari batch pertamastateful=True
, batch kedua melanjutkan batch pertama, memperpanjang urutan yang sama.Ini seperti membagi urutan di windows juga, dengan dua perbedaan utama ini:
stateful=True
akan melihat jendela-jendela ini terhubung sebagai satu urutan panjangDalam
stateful=True
, setiap batch baru akan ditafsirkan sebagai melanjutkan batch sebelumnya (sampai Anda meneleponmodel.reset_states()
).Contoh input, batch 1 berisi langkah 1 dan 2, batch 2 berisi langkah 3 hingga 5:
Perhatikan keselarasan tangki dalam kelompok 1 dan kelompok 2! Itu sebabnya kita perlu
shuffle=False
(kecuali kita hanya menggunakan satu urutan, tentu saja).Anda dapat memiliki sejumlah batch, tanpa batas. (Untuk memiliki panjang variabel dalam setiap batch, gunakan
input_shape=(None,features)
.Satu ke banyak dengan stateful = Benar
Untuk kasus kami di sini, kami hanya akan menggunakan 1 langkah per batch, karena kami ingin mendapatkan satu langkah output dan menjadikannya sebagai input.
Harap perhatikan bahwa perilaku dalam gambar ini bukan "disebabkan oleh"
stateful=True
. Kami akan memaksakan perilaku itu dalam loop manual di bawah ini. Dalam contoh ini,stateful=True
adalah apa yang "memungkinkan" kita untuk menghentikan urutan, memanipulasi apa yang kita inginkan, dan melanjutkan dari tempat kita berhenti.Sejujurnya, pendekatan berulang mungkin merupakan pilihan yang lebih baik untuk kasus ini. Tapi karena kita melihat ke dalam
stateful=True
, ini adalah contoh yang bagus. Cara terbaik untuk menggunakan ini adalah kasus "banyak ke banyak" berikutnya.Lapisan:
Sekarang, kita akan memerlukan loop manual untuk prediksi:
Banyak ke banyak dengan stateful = Benar
Sekarang, di sini, kita mendapatkan aplikasi yang sangat bagus: diberi urutan input, cobalah untuk memprediksi langkah-langkah yang tidak diketahui di masa depan.
Kami menggunakan metode yang sama seperti pada "satu ke banyak" di atas, dengan perbedaan bahwa:
Layer (sama seperti di atas):
Latihan:
Kami akan melatih model kami untuk memprediksi langkah selanjutnya dari urutan:
Memprediksi:
Tahap pertama dari prediksi kami melibatkan "membenarkan negara". Itu sebabnya kita akan memprediksi seluruh urutan lagi, bahkan jika kita sudah tahu bagiannya:
Sekarang kita pergi ke loop seperti pada kasus satu ke banyak. Tapi jangan setel ulang status di sini! . Kami ingin model mengetahui di mana urutan urutannya (dan ia tahu itu pada langkah baru pertama karena prediksi yang baru saja kami buat di atas)
Pendekatan ini digunakan dalam jawaban dan file ini:
Mencapai konfigurasi yang kompleks
Dalam semua contoh di atas, saya menunjukkan perilaku "satu lapisan".
Anda dapat, tentu saja, menumpuk banyak lapisan di atas satu sama lain, tidak semua harus mengikuti pola yang sama, dan membuat model Anda sendiri.
Salah satu contoh menarik yang telah muncul adalah "autoencoder" yang memiliki "banyak ke satu encoder" diikuti oleh decoder "satu ke banyak":
Encoder:
Dekoder:
Menggunakan metode "repeat";
Autoencoder:
Berlatih dengan
fit(X,X)
Penjelasan tambahan
Jika Anda ingin detail tentang bagaimana langkah-langkah dihitung dalam LSTMs, atau detail tentang
stateful=True
kasus - kasus di atas, Anda dapat membaca lebih lanjut dalam jawaban ini: Keraguan mengenai `Memahami Keras LSTMs`sumber
my_cell = LSTM(num_output_features_per_timestep, return_state=True)
, diikuti oleh lingkarana, _, c = my_cell(output_of_previous_time_step, initial_states=[a, c])
Ketika Anda memiliki return_afterences di lapisan terakhir RNN Anda, Anda tidak dapat menggunakan lapisan Dense sederhana sebagai gantinya menggunakan TimeDistributed.
Ini adalah contoh kode yang dapat membantu orang lain.
kata = keras.layers.Input (batch_shape = (Tidak ada, self.maxSequenceLength), name = "input")
sumber