嗯,在我看来,你需要更多地谷歌一下卷积网络:-)
您在每个步骤中在序列上应用 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)
我希望这可以帮助你。
附注如果您想知道 None 是什么,它是批次的维度,您不会一次喂入 1000 个样本,而是逐批次喂入它,并且由于该值取决于所选择的内容,按照惯例,我们设置 None。
EDIT :
进一步解释为什么序列长度在每一步都会丢失一个值。
假设你有一个包含 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'
。你可以在这里阅读更多相关信息并找到不同的可能的值padding争论在这里。我鼓励您阅读最后一个链接,它提供了有关输入和输出形状的信息......
来自文档:
填充:“有效”或“相同”之一(不区分大小写)。 “有效”意味着“无填充”。 “same”会填充输入,使输出与原始输入具有相同的长度。
默认值为“有效”,因此您无需在示例中填充。
我还建议您将 keras 版本升级到最新。 Convolution1D 现在是 Conv1D,因此您可能会发现文档和教程令人困惑。