Python 卷积层失配中的Keras维数

Python 卷积层失配中的Keras维数,python,machine-learning,neural-network,keras,convolution,Python,Machine Learning,Neural Network,Keras,Convolution,我正试着和Keras一起构建我的第一个神经网络。我没有经验,我似乎不明白为什么我的维度不正确。我无法从他们的文档中找出这个错误的原因,甚至无法找出是哪一层造成的 我的模型接受一个32字节的数字数组,应该在另一端给出一个布尔值。我想对输入字节数组进行一维卷积 arr1是32字节数组,arr2是布尔数组 inputData = np.array(arr1) inputData = np.expand_dims(inputData, axis = 2) labelData = np.array(ar

我正试着和Keras一起构建我的第一个神经网络。我没有经验,我似乎不明白为什么我的维度不正确。我无法从他们的文档中找出这个错误的原因,甚至无法找出是哪一层造成的

我的模型接受一个32字节的数字数组,应该在另一端给出一个布尔值。我想对输入字节数组进行一维卷积

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

我收到的错误是:

回溯(最近一次调用):文件“cnn/init.py”,第行 50,英寸 inputData,labelData文件“/home/steve/Documents/cnn/env/local/lib/python2.7/site packages/keras/models.py”, 第863行,合适的 initial_epoch=initial_epoch)文件“/home/steve/Documents/cnn/env/local/lib/python2.7/site packages/keras/engine/training.py”, 第1358行,合适的 批量大小=批量大小)文件“/home/steve/Documents/cnn/env/local/lib/python2.7/site packages/keras/engine/training.py”, 第1238行,标准化用户数据 异常文件“/home/steve/Documents/cnn/env/local/lib/python2.7/site packages/keras/engine/training.py”, 第128行,输入数据 str(array.shape))ValueError:检查目标时出错:预期激活_5有3个维度,但得到了形状为(1000,1)的数组


在我看来,你需要在谷歌上搜索更多关于卷积网络的信息:-)

在每个步骤中,您都要在yout序列上应用32个长度为2的过滤器。因此,如果我们遵循每层后张量的尺寸:

维度:(无、32、1)

维度:(无、31、32) (长度为2的过滤器覆盖整个序列,因此序列现在的长度为31)

维度:(无、30、32) (由于过滤器的长度为2,您再次丢失了一个值,但仍有32个过滤器)

维度:(无、29、32) (相同……)

维度:(无、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的输出

我建议修改最后两层,如下所示:

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)

我希望这对你有帮助

注:如果你想知道“无”是什么,这是批次的尺寸,你不需要一次输入1000个样本,而是一批一批地输入,因为值取决于选择的是什么,按照惯例,我们将“无”

编辑:

进一步解释为什么序列长度在每一步都会丢失一个值

假设您有一个由4个值组成的序列
[x1 x2 x3 x4]
,您希望使用长度为2的过滤器
[f1 f2]
对该序列进行卷积。第一个值由
y1=[f1 f2]*[x1 x2]
给出,第二个值为
y2=[f1 f2]*[x2 x3]
,第三个值为
y3=[f1 f2]*[x3 x4]
。然后,您到达序列的末尾,无法继续。因此,您有一个sequnce
[y1 y2 y3]

这是由于过滤器长度和序列边界处的效果造成的。有多个选项,一些用0填充序列以获得完全相同的输出长度。。。您可以使用参数
“padding”
选择该选项。你可以找到不同的。我鼓励您阅读最后一个链接,它提供了有关输入和输出形状的信息

从文档:

填充:“有效”或“相同”(不区分大小写)之一。“有效”表示“无填充”。“相同”导致填充输入,使输出与原始输入具有相同的长度

默认值为“valid”,因此不在示例中填充


我还建议您将keras版本升级到最新版本。卷积1d现在是Conv1D,因此您可能会发现文档和教程令人困惑。

谢谢!!我明白为什么我现在有维度问题了。我不明白为什么卷积步骤会丢失一个字节?在我看来,卷积是穿过这一行的,对于每一个x,它都与自身和其他x卷积在一起。因此,在我看来,在代码中,这就像是一个嵌套的for循环,我用更多信息编辑了我的答案:)
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.add(k.layers.core.Dense(1))
model.add(k.layers.Activation('sigmoid'))
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'))