2017-07-15 7 views
1

私は最初のニューラルネットワークを構築するためにケラスを使いこなそうとしています。私は経験がなく、なぜ私の次元が正しくないのか分かりません。私は、このエラーが何を訴えているのか、それを引き起こしている層さえ、彼らのドキュメントから把握することはできません。畳み込みレイヤーミスマッチのケラス次元性

私のモデルは、32バイトの数字の配列を取り、反対側にブール値を与えることになっています。入力バイト配列に1D畳み込みが必要です。

arr1は32バイトの配列、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

まあそれは私には思われます

各ステップで、youtシーケンスに32の長さのフィルタを適用しています。だから私たちは、それぞれの層の後テンソルの大きさに従った場合:

外形寸法:(なし、32、1)

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

は、外形寸法:(なし、31、32) (あなたのフィルタを配列は、長さ31)の今であるので長さ2は配列全体にわたって進むの

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のアウトプットを取り出そうとしていることです.32の代わりに1を入れておくべきです。しかし、これでも問題は解決しません。我々は最後の層を変更した場合に何が起こるかを参照してください:

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

寸法:あなたは '2D' テンソルに緻密層を適用しているため(なし、28、1)

これは起こりません。dense(1)レイヤーを入力[28,32]に適用した場合、28個のベクトルに適用される形状(32,1)の重み行列が生成され、28個の出力私はこの問題を解決することを提案すると、このような最後の2層に変更することである1

サイズの:

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')) 

を今すぐ最後の2つの手順が

(なし、29からあなたのテンソルがかかります、32)→(なし、28,1)→(なし、28)→(なし、1)

私はこれがあなたに役立つことを願っています。

ps。何もないと思っていたら、それはバッチの次元です.1000のサンプルをoncesでフィードせず、バッチでバッチをフィードし、値が選択されたものに依存するので、コンボインメントによってNoneを入れます。

EDIT:

配列の長さは、各ステップで一つの値を失う理由をもう少し説明します。

シーケンス番号が[x1 x2 x3 x4]の場合、長さが2 [f1 f2]のフィルタを使用して、シーケンスを畳み込みたいとします。最初の値はy1 = [f1 f2] * [x1 x2]、2番目の値はy2 = [f1 f2] * [x2 x3]、3番目の値は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.

デフォルトは「有効」であるので、あなたがあなたの中にパッドをしないでください例。

ケラスのバージョンを最新のものにアップグレードすることもお勧めします。 Convolution1DはConv1Dになりました。そのため、ドキュメントとチュートリアルが混乱することがあります。

+0

ありがとうございました!なぜ私は今次元の問題を抱えていたのか分かります。畳み込みステップが1バイトを失うのはなぜですか?私の心の中では、畳み込みが行を横切って行き、各xについてそれはそれ自身と他のすべてのxとそれを畳み込んだ。だから、私の心のコードでは、これは同じ配列を2回繰り返すネストされたforループのようだった –

+1

私はこのことについて私の答えを編集しました:) –

関連する問題