मैं अधिकतम लंबाई 50 के गद्देदार अनुक्रमों के साथ काम कर रहा हूं। मेरे पास दो प्रकार के अनुक्रम डेटा हैं:

1) पूर्णांकों का अनुक्रम, seq1, (1-100) जो घटना प्रकारों के अनुरूप है (उदा. [3,6,3,1,45,45...3]

2) seq1 में अंतिम घटना से मिनटों में समय का प्रतिनिधित्व करने वाले पूर्णांकों का अनुक्रम, seq2, । तो अंतिम तत्व शून्य है, परिभाषा के अनुसार। तो उदाहरण के लिए [100, 96, 96, 45, 44, 12,... 0]। seq1 और seq2 समान लंबाई के हैं, 50.

मैं मुख्य रूप से ईवेंट/seq1 डेटा पर LSTM चलाने की कोशिश कर रहा हूं, लेकिन समय/seq2 LSTM के भीतर भूल गेट को दृढ़ता से प्रभावित करता है। इसका कारण यह है कि मैं चाहता हूं कि एलएसटीएम पुरानी घटनाओं को वास्तव में दंडित करे और उन्हें भूलने की अधिक संभावना हो। मैं समय/seq2 अनुक्रम के वर्तमान मूल्य के व्युत्क्रम से भूलने के वजन को गुणा करने के बारे में सोच रहा था। या शायद (1/seq2_element + 1), उन मामलों को संभालने के लिए जहां यह शून्य मिनट है।

मैं केरस कोड (LSTMCell वर्ग) में देखता हूं जहां परिवर्तन होना चाहिए:

f = self.recurrent_activation(x_f + K.dot(h_tm1_f,self.recurrent_kernel_f))

इसलिए मुझे कई इनपुट स्वीकार करने के लिए केरस के LSTM कोड को संशोधित करने की आवश्यकता है। प्रारंभिक परीक्षण के रूप में, LSTMCell वर्ग के भीतर, मैंने इस तरह दिखने के लिए कॉल फ़ंक्शन को बदल दिया:

 def call(self, inputs, states, training=None):
        time_input = inputs[1]
        inputs = inputs[0]

ताकि यह एक सूची के रूप में दिए गए दो इनपुट को हैंडल कर सके।

जब मैं कार्यात्मक एपीआई के साथ मॉडल चलाने की कोशिश करता हूं:

# Input 1: event type sequences
# Take the event integer sequences, run them through an embedding layer to get float vectors, then run through LSTM
main_input = Input(shape =(max_seq_length,), dtype = 'int32', name = 'main_input')
x = Embedding(output_dim = embedding_length, input_dim = num_unique_event_symbols, input_length = max_seq_length, mask_zero=True)(main_input)

## Input 2: time vectors 
auxiliary_input = Input(shape=(max_seq_length,1), dtype='float32', name='aux_input')
m = Masking(mask_value = 99999999.0)(auxiliary_input)

lstm_out = LSTM(32)(x, time_vector = m)

# Auxiliary loss here from first input
auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)

# An abitrary number of dense, hidden layers here
x = Dense(64, activation='relu')(lstm_out)

# The main output node
main_output = Dense(1, activation='sigmoid', name='main_output')(x)

## Compile and fit the model
model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'], loss_weights=[1., 0.2])
print(model.summary())
np.random.seed(21)
model.fit([train_X1, train_X2], [train_Y, train_Y], epochs=1, batch_size=200)

हालांकि, मुझे निम्न त्रुटि मिलती है:

An `initial_state` was passed that is not compatible with `cell.state_size`. Received `state_spec`=[InputSpec(shape=(None, 50, 1), ndim=3)]; however `cell.state_size` is (32, 32)

कोई सलाह?

2
Slyron 9 मई 2018, 20:35

2 जवाब

सबसे बढ़िया उत्तर

आप केरस में डिफ़ॉल्ट आवर्तक परतों के लिए इनपुट की सूची पास नहीं कर सकते। input_spec ठीक हो गया है और आवर्तक कोड एकल टेंसर इनपुट के आधार पर कार्यान्वित किया जाता है जिसे दस्तावेज़ीकरण में भी इंगित किया गया है, अर्थात यह ऐसा नहीं करता है जादुई रूप से एक ही टाइमस्टेप के 2 इनपुट से अधिक पुनरावृति करें और उसे सेल में पास करें। यह आंशिक रूप से इस कारण से है कि कैसे पुनरावृत्तियों को अनुकूलित किया जाता है और नेटवर्क के अनियंत्रित होने पर धारणाएँ बनाई जाती हैं आदि।

अगर आपको 2 इनपुट पसंद हैं, तो आप constants (doc) को उस सेल में भेज सकते हैं, जो टेंसर को वैसे ही पास कर देगा। यह मुख्य रूप से भविष्य में ध्यान मॉडल लागू करने के लिए है। तो 1 इनपुट टाइमस्टेप के साथ पुनरावृति करेगा जबकि दूसरा नहीं करेगा। यदि आप वास्तव में 2 इनपुट को अजगर में zip() की तरह पुनरावृत्त करना पसंद करते हैं, तो आपको एक कस्टम परत लागू करनी होगी।

2
nuric 10 मई 2018, 12:41

मैं यहां एक अलग विचार रखना चाहूंगा। उन्हें आपको केरस कोड को संशोधित करने की आवश्यकता नहीं है।

ईवेंट प्रकारों की एम्बेडिंग परत के बाद, बीता हुआ समय के साथ एम्बेडिंग को स्टैक करें। केरस फ़ंक्शन keras.layers.Concatenate(axis=-1) है। कल्पना कीजिए, एम्बेडिंग परत द्वारा एक एकल प्रकार को n आयामी वेक्टर में मैप किया जाता है। आप बस बीता हुआ समय एम्बेड करने के बाद एक और आयाम के रूप में जोड़ते हैं ताकि यह एक n+1 वेक्टर बन जाए।

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

0
neurite 10 मई 2018, 18:06