2016-10-24 10 views
6

यह प्रश्न github issue भी है। मैं केरास में एक तंत्रिका नेटवर्क बनाना चाहता हूं जिसमें 2 डी संकल्प और एलएसटीएम परत दोनों शामिल हैं।केरास: lstm कनेक्ट करने के लिए reshape और

नेटवर्क को एमएनआईएसटी वर्गीकृत करना चाहिए। एमएनआईएसटी में प्रशिक्षण डेटा 0 से 9 तक हस्तलिखित अंकों की 60000 ग्रे-स्केल छवियां हैं। प्रत्येक छवि 28x28 पिक्सल है।

मैंने छवियों को चार भागों (बाएं/दाएं, ऊपर/नीचे) में विभाजित कर दिया है और एलएसटीएम के लिए अनुक्रम प्राप्त करने के लिए उन्हें चार आदेशों में पुनर्व्यवस्थित किया है।

|  |  |1 | 2| 
|image| -> ------- -> 4 sequences: |1|2|3|4|, |4|3|2|1|, |1|3|2|4|, |4|2|3|1| 
|  |  |3 | 4| 

छोटे उप छवियों का एक आयाम 14 x 14 चार दृश्यों को एक साथ चौड़ाई के साथ खड़ी दिखती हैं है (कोई फर्क नहीं करना चाहिए कि क्या चौड़ाई या ऊंचाई)।

इस आकार के साथ एक सदिश बनाता है [60000, 4, 1, 56, 14] जहां:

  • 60000 नमूने
  • 4 की संख्या है एक क्रम में तत्वों की संख्या है (# timesteps) की
  • 1 रंग की गहराई (ग्रेस्केल)
  • 56 और 14 चौड़ाई और ऊंचाई

अब यह एक Keras मॉडल को दी जानी चाहिए । समस्या सीएनएन और एलएसटीएम के बीच इनपुट आयामों को बदलने के लिए है। मैं ऑनलाइन खोज की है और इस सवाल का पाया: Python keras how to change the size of input after convolution layer into lstm layer

समाधान एक नयी आकृति प्रदान परत जो छवि सपाट लेकिन (के रूप में एक समतल परत जो सब कुछ लेकिन batch_size पतन होगा के खिलाफ) timesteps को बरकरार रखे हुए हो रहा है।

यहाँ मेरी कोड अब तक बताया गया है:

nb_filters=32 
kernel_size=(3,3) 
pool_size=(2,2) 
nb_classes=10 
batch_size=64 

model=Sequential() 

model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], 
    border_mode="valid", input_shape=[1,56,14])) 
model.add(Activation("relu")) 
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1])) 
model.add(Activation("relu")) 
model.add(MaxPooling2D(pool_size=pool_size)) 


model.add(Reshape((56*14,))) 
model.add(Dropout(0.25)) 
model.add(LSTM(5)) 
model.add(Dense(50)) 
model.add(Dense(nb_classes)) 
model.add(Activation("softmax")) 

इस कोड को एक त्रुटि संदेश बनाता है:

ValueError: total size of new array must be unchanged

जाहिर है नयी आकृति प्रदान परत के लिए इनपुट सही नहीं है। एक विकल्प के रूप में, मैं, नयी आकृति प्रदान करने के लिए परत timesteps पास करने का प्रयास भी:

model.add(Reshape((4,56*14))) 

यह सही नहीं लगता है और किसी भी मामले में, त्रुटि ही रहता है।

क्या मैं इसे सही तरीके से कर रहा हूं? क्या एक reshape परत सीएनएन और एलएसटीएम कनेक्ट करने के लिए उचित उपकरण है?

इस समस्या के बजाय जटिल दृष्टिकोण हैं। इस तरह: https://github.com/fchollet/keras/pull/1456 एक समय वितरित परत जो निम्न परतों से टाइमस्टेप आयाम को छिपाने लगती है।

या यह: https://github.com/anayebi/keras-extra सीएनएन और एलएसटीएम के संयोजन के लिए विशेष परतों का एक सेट।

यदि कोई साधारण रिसाव चाल करता है तो समाधान इतने जटिल (कम से कम वे मेरे लिए जटिल लगते हैं) समाधान क्यों हैं?

अद्यतन:

अजीब के ठंड से, मैं भूल गया कि आयाम भी convolutions, (गद्दी की कमी के लिए) पूलिंग से बदल गया है और किया जाएगा। kgrm ने मुझे आयामों की जांच करने के लिए model.summary() का उपयोग करने की सलाह दी।

रिशेप परत से पहले परत का आउटपुट (None, 32, 26, 5), मैंने reshape को model.add(Reshape((32*26*5,))) में बदल दिया है।

अब ValueError चला गया है, बजाय LSTM शिकायत:

Exception: Input 0 is incompatible with layer lstm_5: expected ndim=3, found ndim=2

ऐसा लगता है जैसे मैं पूरे नेटवर्क के माध्यम से timestep आयाम पारित करने के लिए की जरूरत है। मैं उसे कैसे कर सकता हूँ ? अगर मैं कनवल्शन की input_shape में जोड़ने, यह शिकायत भी: Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode="valid", input_shape=[4, 1, 56,14])

Exception: Input 0 is incompatible with layer convolution2d_44: expected ndim=4, found ndim=5

उत्तर

5

अनुसार करने के लिए Convolution2D परिभाषा अपने इनपुट आयाम (samples, channels, rows, cols) साथ 4-आयामी होना चाहिए। यह एक सीधा कारण है कि आपको एक त्रुटि क्यों मिल रही है।

यह हल करने के लिए आपको TimeDistributed रैपर का उपयोग करना होगा। यह आपको उस समय स्थिर (आवर्ती नहीं) परतों का उपयोग करने की अनुमति देता है।

संबंधित मुद्दे