我试图和Keras一起玩,建立我的第一个神经网络。我没有经验,我似乎无法弄清楚为什么我的维度是不对的。我无法从他们的文档中弄清楚这个错误是抱怨什么,甚至是什么层导致它。
我的模型采用32字节的数字数组,并且应该在另一侧给出一个布尔值。我想在输入字节数组上进行1D卷积。
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,)
我收到的错误是:
回溯(最近一次呼叫最后一次):文件" cnn / init .py",行 50,在 inputData,labelData File" /home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/models.py", 第863行,合适 initial_epoch = initial_epoch)File" /home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", 第1358行,合适 batch_size = batch_size)File" /home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", 第1238行,在_standardize_user_data中 exception_prefix =' target')File" /home/steve/Documents/cnn/env/local/lib/python2.7/site-packages/keras/engine/training.py", 第128行,在_standardize_input_data中 str(array.shape))ValueError:检查目标时出错:预期activation_5有3个维度,但得到的数组有形状(1000,1)
答案 0 :(得分:3)
那么在我看来,你需要更多地了解卷积网络: - )
您在每个步骤应用32个长度为2的过滤器。因此,如果我们在每一层之后遵循张量的尺寸:
尺寸:(无,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)
现在你想在它上面使用一个Dense图层......那就是Dense图层在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.
我建议解决这个问题的方法是改变最后两层:
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。如果你想知道什么是无,它是批次的维度,你不要在onces上提供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' s填充序列以获得完全相同的输出长度...您可以使用参数'padding'
选择该选项。您可以read more about this here找到不同的values possible for the padding
argument here。我鼓励你阅读最后一个链接,它提供有关输入和输出形状的信息......
来自doc:
填充:其中一个"有效"或"相同" (不区分大小写)。 "有效"意味着"没有填充"。 "相同的"导致填充输入,使输出与原始输入具有相同的长度。
默认设置为“有效”,因此您不需要填写示例。
我还建议您将keras版本升级到最新版本。 Convolution1D现在是Conv1D,因此您可能会发现文档和教程令人困惑。