卷积层不匹配中的Keras维数

时间:2017-07-15 16:30:10

标签: python machine-learning neural-network keras convolution

我试图和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)

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,因此您可能会发现文档和教程令人困惑。