स्वीकार किए गए उत्तर के पूरक के रूप में, यह उत्तर केरेस व्यवहार और प्रत्येक चित्र को प्राप्त करने के तरीके को दर्शाता है।
सामान्य केर व्यवहार
मानक केरस आंतरिक प्रसंस्करण हमेशा निम्न चित्र के रूप में कई से कई होता है (जहां मैंने features=2
एक उदाहरण के रूप में, दबाव और तापमान का उपयोग किया है ):
इस छवि में, मैंने अन्य आयामों के साथ भ्रम से बचने के लिए, चरणों की संख्या 5 तक बढ़ा दी।
इस उदाहरण के लिए:
- हमारे पास एन तेल टैंक हैं
- हमने 5 घंटे प्रति घंटा उपाय किए (समय कदम)
- हमने दो विशेषताएं मापीं:
हमारे इनपुट एरे को तब कुछ आकार देना चाहिए (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]],
]
स्लाइडिंग विंडो के लिए इनपुट
अक्सर, LSTM परतों को पूरे अनुक्रम को संसाधित करना चाहिए। डिवाइडिंग विंडो सबसे अच्छा विचार नहीं हो सकता है। इस परत में आंतरिक स्थिति है कि कैसे एक क्रम विकसित हो रहा है क्योंकि यह आगे बढ़ता है। विंडोज लंबी अनुक्रम सीखने की संभावना को खत्म करता है, खिड़की के आकार के सभी अनुक्रमों को सीमित करता है।
खिड़कियों में, प्रत्येक खिड़की एक लंबे मूल अनुक्रम का हिस्सा है, लेकिन केरस द्वारा उन्हें प्रत्येक एक स्वतंत्र अनुक्रम के रूप में देखा जाएगा:
[ 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]],
....
]
ध्यान दें कि इस मामले में, आपके पास प्रारंभ में केवल एक अनुक्रम है, लेकिन आप इसे विंडोज़ बनाने के लिए कई अनुक्रमों में विभाजित कर रहे हैं।
"एक अनुक्रम क्या है" की अवधारणा अमूर्त है। महत्वपूर्ण भाग हैं:
- आपके पास कई अलग-अलग दृश्यों के साथ बैच हो सकते हैं
- जो क्रम बनता है वह अनुक्रम है जो वे चरणों में विकसित होते हैं (आमतौर पर समय कदम)
"सिंगल लेयर्स" के साथ प्रत्येक मामले को प्राप्त करना
कई लोगों के लिए मानक प्राप्त करना:
आप एक सरल LSTM परत के साथ कई का उपयोग कर कई प्राप्त कर सकते हैं return_sequences=True
:
outputs = LSTM(units, return_sequences=True)(inputs)
#output_shape -> (batch_size, steps, units)
एक से कई हासिल करना:
सटीक एक ही परत का उपयोग करते हुए, keras सटीक समान आंतरिक प्रीप्रोसेसिंग करेगा, लेकिन जब आप उपयोग करते हैं return_sequences=False
(या बस इस तर्क को अनदेखा करते हैं), तो keras स्वचालित रूप से पिछले से पिछले चरणों को छोड़ देगा:
outputs = LSTM(units)(inputs)
#output_shape -> (batch_size, units) --> steps were discarded, only the last was returned
एक से कई को प्राप्त करना
अब, यह केवल केर एलएसटीएम परतों द्वारा समर्थित नहीं है। आपको चरणों को गुणा करने के लिए अपनी रणनीति बनानी होगी। दो अच्छे दृष्टिकोण हैं:
- किसी टेंसर को दोहराकर लगातार मल्टी-स्टेप इनपुट बनाएं
stateful=True
एक चरण के आउटपुट को बार-बार लेने के लिए उपयोग करें और अगले चरण के इनपुट के रूप में सेवा करें (आवश्यकताएं output_features == input_features
)
दोहराए गए वेक्टर के साथ एक से कई
केरस मानक व्यवहार में फिट होने के लिए, हमें चरणों में इनपुट की आवश्यकता होती है, इसलिए, हम केवल उन लंबाई के इनपुट को दोहराते हैं जो हम चाहते हैं:
outputs = RepeatVector(steps)(inputs) #where inputs is (batch,features)
outputs = LSTM(units,return_sequences=True)(outputs)
#output_shape -> (batch_size, steps, units)
स्थिति समझना = सत्य
अब संभावित उपयोगों में से एक आता है stateful=True
(लोडिंग डेटा से बचने के अलावा जो आपके कंप्यूटर की मेमोरी को एक बार में फिट नहीं कर सकता है)
स्टेटफुल हमें चरणों में अनुक्रमों के "भागों" को इनपुट करने की अनुमति देता है। अंतर यह है:
- में
stateful=False
, दूसरा बैच पूरी नई दृश्यों, पहले बैच से स्वतंत्र होता है
- में
stateful=True
, दूसरा बैच पहले बैच जारी है, एक ही दृश्यों का विस्तार।
यह विंडोज़ में अनुक्रमों को विभाजित करने जैसा है, इन दो मुख्य अंतरों के साथ:
- ये विंडो सुपरपोज नहीं करती हैं !!
stateful=True
इन खिड़कियों को एक एकल लंबे अनुक्रम के रूप में जुड़ा हुआ देखेंगे
में stateful=True
, हर नए बैच पिछले बैच (जब तक आप फोन जारी के रूप में व्याख्या की जाएगी model.reset_states()
)।
- बैच 2 में अनुक्रम 1 बैच 1 में अनुक्रम 1 जारी रखेगा।
- बैच 2 में अनुक्रम 2 बैच 1 में अनुक्रम 2 जारी रखेगा।
- बैच 2 में अनुक्रम n बैच 1 में अनुक्रम n जारी रखेगा।
इनपुट के उदाहरण, बैच 1 में चरण 1 और 2 हैं, बैच 2 में चरण 3 से 5 हैं:
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]],
] ]
बैच 1 और बैच 2 में टैंक के संरेखण पर ध्यान दें! इसलिए हमें ज़रूरत है shuffle=False
(जब तक कि हम केवल एक अनुक्रम का उपयोग नहीं कर रहे हैं, निश्चित रूप से)।
आपके पास अनिश्चित काल के लिए किसी भी संख्या में बैच हो सकते हैं। (प्रत्येक बैच में परिवर्तनशील लंबाई होने के लिए, उपयोग करें input_shape=(None,features)
।
स्टेटफुल = ट्रू के साथ एक से कई
हमारे मामले के लिए, हम प्रति बैच केवल 1 चरण का उपयोग करने जा रहे हैं, क्योंकि हम एक आउटपुट कदम प्राप्त करना चाहते हैं और इसे एक इनपुट बनाते हैं।
कृपया ध्यान दें कि चित्र में व्यवहार "के कारण" नहीं है stateful=True
। हम नीचे दिए गए मैनुअल लूप में उस व्यवहार को बाध्य करेंगे। इस उदाहरण में, stateful=True
वह है जो हमें अनुक्रम को रोकने के लिए "अनुमति देता है", जो हम चाहते हैं, उसमें हेरफेर करें और जहां हम रुके थे, वहां से जारी रखें।
ईमानदारी से, इस मामले के लिए दोहराने का दृष्टिकोण शायद एक बेहतर विकल्प है। लेकिन जब से हम देख रहे हैं stateful=True
, यह एक अच्छा उदाहरण है। इसका उपयोग करने का सबसे अच्छा तरीका अगले "कई से कई" मामले हैं।
परत:
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)
अब, हमें भविष्यवाणियों के लिए एक मैनुअल लूप की आवश्यकता है:
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()
राजकीय = सत्य के साथ बहुत से
अब, यहां, हमें एक बहुत अच्छा अनुप्रयोग मिलता है: एक इनपुट अनुक्रम दिया गया है, इसके भविष्य के अज्ञात चरणों की भविष्यवाणी करने का प्रयास करें।
हम उसी विधि का उपयोग कर रहे हैं जैसे "एक से कई" ऊपर, अंतर के साथ:
- हम अनुक्रम डेटा का उपयोग लक्ष्य डेटा के लिए करेंगे, एक कदम आगे
- हम अनुक्रम का हिस्सा जानते हैं (इसलिए हम परिणामों के इस भाग को छोड़ देते हैं)।
परत (ऊपर के समान):
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)
प्रशिक्षण:
हम अनुक्रम के अगले चरण की भविष्यवाणी करने के लिए अपने मॉडल को प्रशिक्षित करने जा रहे हैं:
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)
भविष्यवाणी:
हमारी भविष्यवाणी के पहले चरण में "राज्यों के साथ अन्याय" शामिल है। इसलिए हम फिर से पूरे अनुक्रम की भविष्यवाणी करने जा रहे हैं, भले ही हम पहले से ही इसके बारे में जानते हों:
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
अब हम लूप में जाते हैं क्योंकि एक से कई मामलों में। लेकिन यहाँ राज्यों को रीसेट न करें! । हम चाहते हैं कि मॉडल यह जानना चाहता है कि यह अनुक्रम के किस चरण में है (और यह जानता है कि यह पहले नए चरण में है क्योंकि हम ऊपर दिए गए भविष्यवाणी के अनुसार हैं)
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()
इस दृष्टिकोण का उपयोग इन उत्तरों और फ़ाइल में किया गया था:
जटिल विन्यास प्राप्त करना
उपरोक्त सभी उदाहरणों में, मैंने "एक परत" का व्यवहार दिखाया।
आप निश्चित रूप से, एक-दूसरे के ऊपर कई परतों को ढेर कर सकते हैं, जरूरी नहीं कि सभी समान पैटर्न का पालन करें, और अपने स्वयं के मॉडल बनाएं।
एक दिलचस्प उदाहरण जो दिखाई दे रहा है वह है "ऑटोकेनोडर" जिसमें "एक से कई एनकोडर" होते हैं और उसके बाद "एक से कई" डिकोडर होते हैं:
एनकोडर:
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)
डिकोडर:
"दोहराने" विधि का उपयोग करना;
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)
के साथ ट्रेन fit(X,X)
अतिरिक्त स्पष्टीकरण
यदि आप LSTM में चरणों की गणना कैसे करते हैं, या stateful=True
उपरोक्त मामलों के बारे में विवरण चाहते हैं, तो आप इस उत्तर में और अधिक पढ़ सकते हैं: 'करस LSTMs' को समझना