केरस में विभिन्न लंबाई के उदाहरणों के साथ एक आरएनएन का प्रशिक्षण


61

मैं RNN के बारे में सीखना शुरू करने की कोशिश कर रहा हूं और मैं केर का उपयोग कर रहा हूं। मैं वेनिला RNN और LSTM परतों के मूल आधार को समझता हूं, लेकिन मुझे प्रशिक्षण के लिए एक निश्चित तकनीकी बिंदु को समझने में परेशानी हो रही है।

में keras प्रलेखन , यह कहता है कि एक RNN परत के लिए इनपुट आकार होना आवश्यक है (batch_size, timesteps, input_dim)। इससे पता चलता है कि सभी प्रशिक्षण उदाहरणों की एक निश्चित अनुक्रम लंबाई है, अर्थात् timesteps

लेकिन यह विशेष रूप से विशिष्ट नहीं है, क्या यह है? मैं अलग-अलग लंबाई के वाक्यों पर RNN संचालित करना चाहता हूं। जब मैं इसे कुछ कॉर्पस पर प्रशिक्षित करता हूं, तो मैं इसे वाक्यों के बैच खिलाऊंगा, सभी अलग-अलग लंबाई के।

मुझे लगता है कि स्पष्ट बात यह है कि प्रशिक्षण सेट और शून्य पैड में किसी भी अनुक्रम की अधिकतम लंबाई का पता लगाना होगा। लेकिन तब इसका मतलब यह है कि मैं परीक्षण समय पर भविष्यवाणियां इनपुट लंबाई से अधिक नहीं कर सकता हूं?

यह केरस के विशेष कार्यान्वयन के बारे में एक सवाल है, मुझे लगता है, लेकिन मैं यह भी पूछ रहा हूं कि आम तौर पर इस तरह की समस्या का सामना करने पर लोग आमतौर पर क्या करते हैं।


@ चक्र सही है। हालाँकि, मेरी एक चिंता है। उदाहरण में, आपके पास असीम पैदावार का एक बहुत ही विशेष जनरेटर है। इससे भी महत्वपूर्ण बात, यह आकार 1000 के बैचों को तैयार करने के लिए बनाया गया है। व्यवहार में, यह बहुत मुश्किल है, अगर यह असंभव नहीं है। आपको अपनी प्रविष्टियों को फिर से व्यवस्थित करने की आवश्यकता है ताकि समान लंबाई वाले लोगों को एक साथ व्यवस्थित किया जाए, और आपको बैच विभाजन पदों को ध्यान से सेट करने की आवश्यकता है। इसके अलावा, आपके पास बैचों में फेरबदल करने का कोई मौका नहीं है। तो मेरी राय है: केरस में कभी भी अलग-अलग लंबाई के इनपुट का उपयोग न करें जब तक कि आपको वास्तव में पता नहीं है कि आप क्या कर रहे हैं। Maskingअज्ञानता के लिए पैडिंग और सेट लेयर का उपयोग करें
Bs He

जवाबों:


57

इससे पता चलता है कि सभी प्रशिक्षण उदाहरणों की एक निश्चित अनुक्रम लंबाई है, अर्थात् timesteps

यह काफी सही नहीं है, क्योंकि यह आयाम हो सकता है None, अर्थात परिवर्तनशील लंबाई। एक एकल बैच के भीतर , आपके पास टाइमस्टेप्स की समान संख्या होनी चाहिए (यह आमतौर पर जहां आप 0-पेडिंग और मास्किंग देखते हैं)। लेकिन बैचों के बीच ऐसा कोई प्रतिबंध नहीं है। अनुमान के दौरान, आपकी कोई भी लंबाई हो सकती है।

उदाहरण कोड जो प्रशिक्षण डेटा के यादृच्छिक समय-लंबाई बैच बनाता है।

from keras.models import Sequential
from keras.layers import LSTM, Dense, TimeDistributed
from keras.utils import to_categorical
import numpy as np

model = Sequential()

model.add(LSTM(32, return_sequences=True, input_shape=(None, 5)))
model.add(LSTM(8, return_sequences=True))
model.add(TimeDistributed(Dense(2, activation='sigmoid')))

print(model.summary(90))

model.compile(loss='categorical_crossentropy',
              optimizer='adam')

def train_generator():
    while True:
        sequence_length = np.random.randint(10, 100)
        x_train = np.random.random((1000, sequence_length, 5))
        # y_train will depend on past 5 timesteps of x
        y_train = x_train[:, :, 0]
        for i in range(1, 5):
            y_train[:, i:] += x_train[:, :-i, i]
        y_train = to_categorical(y_train > 2.5)
        yield x_train, y_train

model.fit_generator(train_generator(), steps_per_epoch=30, epochs=10, verbose=1)

और यही वह प्रिंट करता है। नोट आउटपुट आकृतियाँ (None, None, x)चर बैच आकार और चर टाइमस्टेप आकार का संकेत दे रही हैं ।

__________________________________________________________________________________________
Layer (type)                            Output Shape                        Param #
==========================================================================================
lstm_1 (LSTM)                           (None, None, 32)                    4864
__________________________________________________________________________________________
lstm_2 (LSTM)                           (None, None, 8)                     1312
__________________________________________________________________________________________
time_distributed_1 (TimeDistributed)    (None, None, 2)                     18
==========================================================================================
Total params: 6,194
Trainable params: 6,194
Non-trainable params: 0
__________________________________________________________________________________________
Epoch 1/10
30/30 [==============================] - 6s 201ms/step - loss: 0.6913
Epoch 2/10
30/30 [==============================] - 4s 137ms/step - loss: 0.6738
...
Epoch 9/10
30/30 [==============================] - 4s 136ms/step - loss: 0.1643
Epoch 10/10
30/30 [==============================] - 4s 142ms/step - loss: 0.1441

इसके लिए शुक्रिया। हालाँकि, यदि हम अनुक्रम को पैड करते हैं, तो यह छिपे हुए राज्यों और मेमोरी सेल को प्रभावित करेगा क्योंकि हम x_t को 0s के रूप में जारी रखते हैं, जब कि यदि तथ्य है, तो कुछ भी पारित नहीं होना चाहिए। सामान्य में fit(), हम sequence_lenthइसे बाहर करने के लिए अनुक्रम की लंबाई निर्दिष्ट करने के लिए पैरामीटर पारित कर सकते हैं । ऐसा लगता है कि जनरेटर दृष्टिकोण 0 दृश्यों की अनदेखी करने की अनुमति नहीं देता है?
जीआरएस

1
@GRS आपका जनरेटर 3-टपल वापस कर सकता है (inputs, targets, sample_weights), और आप sample_weightsअपने 0-पैड को 0. पर सेट कर सकते हैं । हालांकि, मुझे यकीन नहीं है कि यह बिडायरेक्शनल आरएनएन के लिए पूरी तरह से काम करेगा।
kbrose

यह मददगार रहा है, लेकिन मेरी इच्छा है कि इसमें model.predict_generatorएक परीक्षण सेट के साथ उपयोग करने का एक उदाहरण भी शामिल होगा । जब मैं एक जनरेटर के साथ भविष्यवाणी करने की कोशिश करता हूं, तो मुझे कॉन्सेटेशन के संबंध में एक त्रुटि मिलती है (परीक्षण सेट में परिवर्तनशील लंबाई अनुक्रम भी होता है)। मेरा समाधान मानक का उपयोग model.predictहैकरी तरीके से करना है। शायद यह सिर्फ एक नए सवाल के लिए बेहतर होगा?
मिकी

@ मिकी जो एक अलग प्रश्न की तरह लगता है। यह सवाल प्रशिक्षण के बारे में है, न कि भविष्यवाणी के बारे में।
kbrose

यदि टिप्पणियों में प्रश्न वास्तव में एक नए प्रश्न के रूप में पूछा गया था, तो क्या आप इसे लिंक कर सकते हैं?
इटाराम मुश्किन

7

@kbrose के पास एक बेहतर उपाय है

मुझे लगता है कि स्पष्ट बात यह है कि प्रशिक्षण सेट और शून्य पैड में किसी भी अनुक्रम की अधिकतम लंबाई का पता लगाना होगा।

यह आमतौर पर एक अच्छा उपाय है। शायद अनुक्रम की अधिकतम लंबाई की कोशिश करें + 100. जो भी आपके आवेदन के लिए सबसे अच्छा काम करता है उसका उपयोग करें।

लेकिन तब इसका मतलब यह है कि मैं परीक्षण समय पर भविष्यवाणियां इनपुट लंबाई से अधिक नहीं कर सकता हूं?

जरुरी नहीं। कार्स में एक निश्चित लंबाई का उपयोग किया जाता है, इसका कारण यह है कि यह निश्चित आकृतियों के दसियों को बनाकर प्रदर्शन में सुधार करता है। लेकिन यह केवल प्रशिक्षण के लिए है। प्रशिक्षण के बाद, आपने अपने कार्य के लिए सही वजन सीखा है।

मान लेते हैं, घंटों प्रशिक्षण के बाद, आप महसूस करते हैं कि आपके मॉडल की अधिकतम लंबाई बड़ी / छोटी नहीं थी और आपको अब समय के कदम बदलने की जरूरत है, बस पुराने मॉडल से सीखे हुए वज़न को निकालें, नए समय के चरणों के साथ एक नया मॉडल बनाएं और इसमें सीखे गए वज़न को इंजेक्ट करें।

आप शायद कुछ का उपयोग करके ऐसा कर सकते हैं:

new_model.set_weights(old_model.get_weights())

मैंने खुद इसे आज़माया नहीं है। कृपया इसे आज़माएं और सभी के लाभ के लिए अपने परिणाम यहां पोस्ट करें। यहाँ कुछ लिंक दिए गए हैं: एक दो


1
आपके पास वास्तव में चर लंबाई इनपुट हो सकते हैं, जैसे हैक्स को पेश करने की कोई आवश्यकता नहीं है max length + 100। उदाहरण कोड के लिए मेरा जवाब देखें।
kbrose

1
अधिक समय के साथ एक मॉडल को वज़न स्थानांतरित करना वास्तव में पूरी तरह से ठीक काम करता है! मैं समय Bidirectional(LSTM)()और RepeatVector()परतों के लिए टकराया , और भविष्यवाणियां पूरी तरह से व्यवहार्य हैं।
komodovaran_

@kbrose यह हैक नहीं है, यह है कि आप सामान्य रूप से इसे कैसे करते हैं। किसी के बैच_साइज़ का उपयोग करना बहुत धीमा है और केरेस परतों को मास्क करने में सक्षम बनाता है ताकि मास्किंग नुकसान को प्रभावित न करे।
फेरस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.