2017-07-15 111 views
1

我正在嘗試與Keras一起構建我的第一個神經網絡。我沒有經驗,我似乎無法弄清楚爲什麼我的維度不對。我無法從他們的文檔中弄清楚這個錯誤是在抱怨什麼,甚至是什麼層造成的。卷積層錯配Keras維數

我的模型需要一個32byte的數字數組,並且應該在另一邊給出一個布爾值。我想在輸入字節數組上進行一維卷積。

arr1是32byte數組,arr2是布爾值數組。

inputData = np.array(arr1) 
inputData = np.expand_dims(inputData, axis = 2) 

labelData = np.array(arr2) 

print inputData.shape 
print labelData.shape 

model = k.models.Sequential() 
model.add(k.layers.convolutional.Convolution1D(32,2, input_shape = (32, 1))) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.core.Dense(32)) 
model.add(k.layers.Activation('sigmoid')) 

model.compile(loss = 'binary_crossentropy', 
       optimizer = 'rmsprop', 
       metrics=['accuracy']) 
model.fit(
    inputData,labelData 
) 

形狀的打印的輸出是 (1000,32,1)和(1000)

我收到的錯誤是:

Traceback (most recent call last): File "cnn/init.py", line 50, in inputData,labelData File "/home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/models.py", line 863, in fit initial_epoch=initial_epoch) File "/home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", line 1358, in fit batch_size=batch_size) File "/home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", line 1238, in _standardize_user_data exception_prefix='target') File "/home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", line 128, in _standardize_input_data str(array.shape)) ValueError: Error when checking target: expected activation_5 to have 3 dimensions, but got array with shape (1000, 1)

回答

2

那麼在我看來,您需要更多關於卷積網絡的谷歌:-)

您正在申請在每個步驟32過濾器的長度2 yout序列。因此,如果我們按照張量的尺寸每層之後:

尺寸:(無,32,1)

model.add(k.layers.convolutional.Convolution1D(32,2, input_shape = (32, 1))) 
model.add(k.layers.Activation('relu')) 

尺寸:(無,31,32) (您的過濾器的長度爲2越過整個序列,以便該序列現在是長度爲31)的

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

尺寸:(無,30,32) (你又失去了一個值,因爲您的長度爲2的過濾器,但你仍然有他們的32)

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

尺寸:(無,29,32) (同...)

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

尺寸:(無,28,32)

現在你想最重要的是使用緻密層......事情是,緻密層將作爲按照信息3D輸入:

model.add(k.layers.core.Dense(32)) 
model.add(k.layers.Activation('sigmoid')) 

尺寸:(無,28,32)

這是您的輸出。我發現奇怪的第一件事是,你需要32個輸出你的密集層...你應該把1而不是32。但即使這不會解決你的問題。看看我們是否改變最後一層會發生什麼:

model.add(k.layers.core.Dense(1)) 
model.add(k.layers.Activation('sigmoid')) 

尺寸:(無,28,1)

這是因爲你申請一個緻密層的 '2D' 張量。如果將密集(1)圖層應用到輸入[28,32],它會產生一個形狀(32,1)的權重矩陣,它適用於28個矢量,以便您可以找到28個輸出大小1.

我建議解決這個問題是什麼是改變過去的2層是這樣的:

model = k.models.Sequential() 
model.add(k.layers.convolutional.Convolution1D(32,2, input_shape = (32, 1))) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

model.add(k.layers.convolutional.Convolution1D(32,2)) 
model.add(k.layers.Activation('relu')) 

# Only use one filter so that the output will be a sequence of 28 values, not a matrix. 
model.add(k.layers.convolutional.Convolution1D(1,2)) 
model.add(k.layers.Activation('relu')) 

# Change the shape from (None, 28, 1) to (None, 28) 
model.add(k.layers.core.Flatten()) 

# Only one neuron as output to get the binary target. 
model.add(k.layers.core.Dense(1)) 
model.add(k.layers.Activation('sigmoid')) 

現在最後兩個步驟將您從張

(無,29 ,32) - >(無,28,1) - >(無,28) - >(無,1)

我希望這可以幫助你。

ps。如果你想知道什麼是無,它就是批次的維度,你不會在1000個樣本中餵食,你按批次餵食,並且由於價值取決於選擇的東西,所以我們把它放在無。

編輯:

解釋多一點爲什麼序列長度失去在每一步一個值。假設您有4個值的序列[x1 x2 x3 x4],您希望使用長度爲2 [f1 f2]的過濾器對序列進行卷積。第一個值將由y1 = [f1 f2] * [x1 x2]給出,第二個將爲y2 = [f1 f2] * [x2 x3],第三個將爲y3 = [f1 f2] * [x3 x4]。然後你到達序列的末尾,不能再走了。結果你有一個結果[y1 y2 y3]

這是由於過濾器長度和序列邊界處的影響。有多種選擇,有些選項用0填充序列以獲得完全相同的輸出長度...您可以使用參數'padding'選擇該選項。您可以read more about this here並找到不同的values possible for the padding argument here。我建議你閱讀這最後一個環節,它提供了有關輸入和輸出的形狀信息...

從DOC:

padding: One of "valid" or "same" (case-insensitive). "valid" means "no padding". "same" results in padding the input such that the output has the same length as the original input.

默認爲「有效」,讓你在不墊您例。

我還建議您將keras版本升級到最新版本。 Convolution1D現在是Conv1D,所以你可能會發現文檔和教程混淆。

+0

謝謝!我明白了爲什麼我現在有維度問題。我不明白爲什麼卷積步驟丟失一個字節?在我看來,卷積橫跨整行,並且對於每個x,它將自身和其他x進行卷積。所以在我腦海中的代碼中,這就像一個嵌套的for循環遍歷相同的數組兩次 –

+1

我編輯了我的答案,更多關於這方面的信息:) –