Am încercat să împace inteleg de LSTMs și a subliniat aici, în acest post de Christopher Olah puse în aplicare în Keras. Sunt urma blog scris de Jason Brownlee pentru Keras tutorial. Ce sunt, în principal, confuză, este,
Vă permite să se concentreze pe cele două întrebări de mai sus cu referință la codul copiat mai jos:
# 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()
Notă: create_dataset nevoie de o secvență de lungime N și returnează o N-look_back
matrice de care fiecare element este un look_back` lungimea secvenței.
După cum se poate observa TrainX este un 3-D matrice cu Time_steps și Caracteristică fiind ultimele două dimensiuni, respectiv, (3 și 1 din acest cod special). Cu privire la imaginea de mai jos, acest lucru înseamnă că avem în vedere a
caz, în cazul în care numărul de cutii roz sunt 3? Sau nu-l literalmente înseamnă lungimea lanțului este de 3 (de exemplu, doar 3 cutii verzi considerat).
Are caracteristici argument devin relevante atunci când luăm în considerare multivariată serie? de exemplu, modelarea două stocuri financiare simultan?
Nu statefull LSTMs înseamnă că ne vom salva de celule de memorie valori între ruleaza de loturi? Dacă acesta este cazul, batch_size
este una, iar memoria este resetat între formarea se execută atât de ceea ce a fost pe punctul de a spune că a fost dinamică. Am'm ghicitul acest lucru este legat de faptul că datele de formare nu este amestecat, dar eu'm nu sunt sigur cum.
Orice gânduri? Imagine de referință: http://karpathy.github.io/2015/05/21/rnn-effectiveness/
Un pic confuz cu privire la @van's comentariu despre roșu și verde cutii fiind egale. Deci, doar pentru a confirma, face următoarele apeluri API corespund derulat diagrame? Mai ales de remarcat cea de-a doua diagramă (batch_size
a fost ales în mod arbitrar.):
Pentru persoanele care au făcut Udacity's învățare profundă curs și încă confuz despre time_step argument, uita-te la următoarea discuție: https://discussions.udacity.com/t/rnn-lstm-use-implementation/163169
Se pare model.adaugă(TimeDistributed(Dens(vocab_len)))
a fost ceea ce am fost în căutarea pentru. Aici este un exemplu: https://github.com/sachinruk/ShakespeareBot
Am sintetizat mai presus de înțelegerea mea de LSTMs aici:
Mai întâi de toate, alege mare de tutoriale(1,2) pentru a începe.
La ce Oră pas înseamnă: Timp pași==3
în X. forma (Descrierea datelor formă) înseamnă că există trei cutii roz. Deoarece în Keras fiecare pas necesită o intrare, prin urmare, numărul de cutii verzi ar trebui să, de obicei egal cu numărul de cutii roșii. Dacă nu ai hack structura.
la mulți la mulți vs. a: În keras, există o return_sequences
parametru atunci când inițializarea LSTM " sau " GRU " sau " SimpleRNN
. Când return_sequenceseste "Fals" (implicit), atunci este **a** după cum se arată în imagine. Revenirea de formă este
(batch_size, hidden_unit_length), care reprezintă ultimul stat. Când return_sequenceseste
Adevărat, atunci este **mai multe la mai multe**. Revenirea de formă este
(batch_size, time_step, hidden_unit_length)`
Are caracteristici argument devin relevante: Caracteristică argument înseamnă "Cât de mare este red box" sau ce este de intrare de dimensiune fiecare pas. Dacă doriți pentru a prezice de la, să zicem, 8 tipuri de informații de piață, atunci puteți genera date cu feature==8`.
Stateful: puteți căuta codul sursă. Atunci când inițializarea stat, dacă statefull==True
, atunci statul de la ultimul antrenament va fi folosit ca starea inițială, în caz contrar se va genera un nou stat. Nu am't porniți statefull încă. Cu toate acestea, nu sunt de acord cu faptul că
batch_sizepoate fi doar 1 când statefull==True
.
În prezent, generarea de date cu datele colectate. Imaginea de informații stocul se apropie ca flux, mai degrabă decât de așteptare pentru o zi pentru a colecta toate secvențială, v-ar dori pentru a genera date de intrare online, în timp ce de formare/prezicerea cu rețea. Dacă aveți 400 de stocurile de partajare o aceeași rețea, apoi puteți seta batch_size==400
.
Ca o completare la răspunsul acceptat, acest răspuns arată keras comportamentele și modul de a realiza fiecare imagine.
Standard keras de procesare internă este întotdeauna o multe de mulți ca în imaginea de mai jos (în cazul în care am folosit are=2
, presiunea și temperatura, doar ca un exemplu):
În această imagine, am crescut numărul de pași la 5, pentru a evita confuzia cu alte dimensiuni.
Pentru acest exemplu:
(N,5,2)
: [ Step1 Step2 Step3 Step4 Step5
Tank A: [[Pa1,Ta1], [Pa2,Ta2], [Pa3,Ta3], [Pa4,Ta4], [Pa5,Ta5]],
Tank B: [[Pb1,Tb1], [Pb2,Tb2], [Pb3,Tb3], [Pb4,Tb4], [Pb5,Tb5]],
....
Tank N: [[Pn1,Tn1], [Pn2,Tn2], [Pn3,Tn3], [Pn4,Tn4], [Pn5,Tn5]],
]
De multe ori, LSTM straturi ar trebui să proceseze întreaga secvențe. Împărțirea windows poate să nu fie cea mai bună idee. Stratul are internă membre despre cum o secvență evoluează ca acesta pași înainte. Windows elimina posibilitatea de învățare secvențe lungi, limitând toate secvențele la dimensiunea ferestrei. În ferestre, fiecare fereastră este un original secvență, dar de Keras ei vor fi văzut ca o secvență independentă:
[ Step1 Step2 Step3 Step4 Step5
Window A: [[P1,T1], [P2,T2], [P3,T3], [P4,T4], [P5,T5]],
Window B: [[P2,T2], [P3,T3], [P4,T4], [P5,T5], [P6,T6]],
Window C: [[P3,T3], [P4,T4], [P5,T5], [P6,T6], [P7,T7]],
....
]
Observați că în acest caz, trebuie inițial doar o secvență, dar're împărțind-o în mai multe secvențe pentru a crea windows. Conceptul de "ce este o secvență" este abstractă. Părțile importante sunt:
Puteți obține mai multe la mai multe, cu un simplu LSTM strat, folosind
return_sequences=True
:
outputs = LSTM(units, return_sequences=True)(inputs)
#output_shape -> (batch_size, steps, units)
Folosind exact același strat, keras va face exact același interne de preprocesare, dar atunci când utilizați return_sequences=False
(sau pur și simplu ignora acest argument), keras automat aruncați pașii anteriori până la ultimul:
outputs = LSTM(units)(inputs)
#output_shape -> (batch_size, units) --> steps were discarded, only the last was returned
Acum, acest lucru nu este susținută de keras LSTM straturi singur. Va trebui să creați-vă propria strategie pentru a multiplicate pașii. Există două abordări:
periodic pentru a lua la ieșire de un pas și se servește ca intrare de la pasul următor (are nevoie de output_features == input_features
) În scopul de a se potrivi pentru a keras standard de comportament, avem nevoie de intrări în etape, astfel încât, pur și simplu repetați intrari pentru lungimea vrem:
outputs = RepeatVector(steps)(inputs) #where inputs is (batch,features)
outputs = LSTM(units,return_sequences=True)(outputs)
#output_shape -> (batch_size, steps, units)
Acum vine una dintre posibilele utilizări ale statefull=True
(în afară de evitarea încărcării date care pot't se potrivi computer's memorie la o dată)
Statefull ne permite să introduceți "piese" de secvențe în etape. Diferența este:
statefull=False
, cel de-al doilea lot cuprinde nouă secvențe, independent de primul lot statefull=True
, cel de-al doilea lot continuă primul lot, extinderea aceleași secvențe.
L's place împărțirea secvențe în windows asemenea, cu aceste două diferențe principale: statefull=True
se va vedea aceste ferestre conectat ca o singură secvență lungă
În statefull=True
, fiecare nou lot va fi interpretată ca o continuare lotul precedent (până te sun model.reset_states()
). BATCH 1 BATCH 2
[ Step1 Step2 | [ Step3 Step4 Step5
Tank A: [[Pa1,Ta1], [Pa2,Ta2], | [Pa3,Ta3], [Pa4,Ta4], [Pa5,Ta5]],
Tank B: [[Pb1,Tb1], [Pb2,Tb2], | [Pb3,Tb3], [Pb4,Tb4], [Pb5,Tb5]],
.... |
Tank N: [[Pn1,Tn1], [Pn2,Tn2], | [Pn3,Tn3], [Pn4,Tn4], [Pn5,Tn5]],
] ]
Observa alinierea de tancuri într-lot 1 și lot 2! Ca's de ce avem nevoie de shuffle=False(dacă suntem folosind doar o secvență, desigur). Puteți avea orice număr de loturi, pe termen nelimitat. (Pentru a avea lungimi variabile în fiecare lot, folosesc input_shape=(Niciunul,caracteristici)
.
Pentru cazul nostru, vom folosi doar 1 pas pe lot, pentru că am vrut pentru a obține o ieșire pas și să-l fi o intrare.
Vă rog să observați că comportamentul în imagine nu este "cauzate de" statefull=True
. Vom forța care comportamentul într-un manual de bucla de mai jos. În acest exemplu, statefull=True
ce este "permite" ne pentru a opri secvența, manipula ceea ce ne dorim, și de a continua de unde ne-am oprit.
Sincer, repet abordare este probabil o alegere mai bună pentru acest caz. Dar când ne-am're în căutarea în
statefull=True
, acesta este un bun exemplu. Cel mai bun mod de a utiliza acest lucru este urmatorul "mai multe de multe" caz.
Strat:
outputs = LSTM(units=features,
stateful=True,
return_sequences=True, #just to keep a nice output shape even with length 1
input_shape=(None,features))(inputs)
#units = features because we want to use the outputs as inputs
#None because we want variable length
#output_shape -> (batch_size, steps, units)
Acum, ne-am're de gând să nevoie de un manual buclă pentru predictii:
input_data = someDataWithShape((batch, 1, features))
#important, we're starting new sequences, not continuing old ones:
model.reset_states()
output_sequence = []
last_step = input_data
for i in steps_to_predict:
new_step = model.predict(last_step)
output_sequence.append(new_step)
last_step = new_step
#end of the sequences
model.reset_states()
Acum, aici, vom obține o aplicație foarte frumos: dat-o secvență de intrare, să încerce să prezică viitorul său necunoscut de pași. Am're folosind aceeași metodă ca și în "una la mai multe" de mai sus, cu diferența că:
outputs = LSTM(units=features,
stateful=True,
return_sequences=True,
input_shape=(None,features))(inputs)
#units = features because we want to use the outputs as inputs
#None because we want variable length
#output_shape -> (batch_size, steps, units)
Formare: Avem de gând să ne antrenăm model pentru a prezice următorul pas al secvențe:
totalSequences = someSequencesShaped((batch, steps, features))
#batch size is usually 1 in these cases (often you have only one Tank in the example)
X = totalSequences[:,:-1] #the entire known sequence, except the last step
Y = totalSequences[:,1:] #one step ahead of X
#loop for resetting states at the start/end of the sequences:
for epoch in range(epochs):
model.reset_states()
model.train_on_batch(X,Y)
Estimarea: Prima etapă a noastră estimarea implică "ajusting state". Ca's de ce am're de gând să prezică întreaga secvență din nou, chiar dacă știm deja partea asta:
model.reset_states() #starting a new sequence
predicted = model.predict(totalSequences)
firstNewStep = predicted[:,-1:] #the last step of the predictions is the first future step
Acum mergem la bucla ca la una la mai multe case. Dar don't resetare membre aici!. Dorim ca modelul să știu în care pas din secvența este (și ea știe asta's de la primul pas nou pentru că de predicție ne-am făcut mai sus)
output_sequence = [firstNewStep]
last_step = firstNewStep
for i in steps_to_predict:
new_step = model.predict(last_step)
output_sequence.append(new_step)
last_step = new_step
#end of the sequences
model.reset_states()
Această abordare a fost utilizată în aceste răspunsuri și fișiere:
În toate exemplele de mai sus, am arătat comportamentul "un strat". Puteți, desigur, stiva mai multe straturi pe partea de sus a reciproc, nu a priori, neapărat toate după același model, și de a crea propriile modele. Un exemplu interesant care a fost să apară este "autoencoder", care are o "mai multe de la un encoder" urmat de un "una la mai multe" decoder: Encoder:
inputs = Input((steps,features))
#a few many to many layers:
outputs = LSTM(hidden1,return_sequences=True)(inputs)
outputs = LSTM(hidden2,return_sequences=True)(outputs)
#many to one layer:
outputs = LSTM(hidden3)(outputs)
encoder = Model(inputs,outputs)
Decoder: Folosind "se repeta de" metodă;
inputs = Input((hidden3,))
#repeat to make one to many:
outputs = RepeatVector(steps)(inputs)
#a few many to many layers:
outputs = LSTM(hidden4,return_sequences=True)(outputs)
#last layer
outputs = LSTM(features,return_sequences=True)(outputs)
decoder = Model(inputs,outputs)
Autoencoder:
inputs = Input((steps,features))
outputs = encoder(inputs)
outputs = decoder(outputs)
autoencoder = Model(inputs,outputs)
Tren cu fit(X,X)
Daca vrei detalii despre cum pașii sunt calculate în LSTMs, sau detalii despre statefull=True
cazuri de mai sus, puteți citi mai multe în acest răspuns: https://stackoverflow.com/questions/53955093/doubts-regarding-understanding-keras-lstms
Când ai return_sequences în ultimul strat de RNN nu puteți utiliza un simplu strat Dens folosi în loc de TimeDistributed.
Aici este un exemplu bucată de cod acest lucru ar putea ajuta pe alții.
cuvinte = keras.straturi.De intrare(batch_shape=(Niciunul, auto.maxSequenceLength), nume = "de intrare")
# Build a matrix of size vocabularySize x EmbeddingDimension
# where each row corresponds to a "word embedding" vector.
# This layer will convert replace each word-id with a word-vector of size Embedding Dimension.
embeddings = keras.layers.embeddings.Embedding(self.vocabularySize, self.EmbeddingDimension,
name = "embeddings")(words)
# Pass the word-vectors to the LSTM layer.
# We are setting the hidden-state size to 512.
# The output will be batchSize x maxSequenceLength x hiddenStateSize
hiddenStates = keras.layers.GRU(512, return_sequences = True,
input_shape=(self.maxSequenceLength,
self.EmbeddingDimension),
name = "rnn")(embeddings)
hiddenStates2 = keras.layers.GRU(128, return_sequences = True,
input_shape=(self.maxSequenceLength, self.EmbeddingDimension),
name = "rnn2")(hiddenStates)
denseOutput = TimeDistributed(keras.layers.Dense(self.vocabularySize),
name = "linear")(hiddenStates2)
predictions = TimeDistributed(keras.layers.Activation("softmax"),
name = "softmax")(denseOutput)
# Build the computational graph by specifying the input, and output of the network.
model = keras.models.Model(input = words, output = predictions)
# model.compile(loss='kullback_leibler_divergence', \
model.compile(loss='sparse_categorical_crossentropy', \
optimizer = keras.optimizers.Adam(lr=0.009, \
beta_1=0.9,\
beta_2=0.999, \
epsilon=None, \
decay=0.01, \
amsgrad=False))