0

我正在训练 1DConv 模型,每个实例有 4248 个实例和 39249 个特征。我正在尝试批量大小为 32 的 VGG16 模型,但在 7 层之后它返回以下错误。

conv1d_8/convolution/Conv2D (op: 'Conv2D') 的 1 减去 3 导致的负维度大小,输入形状为:[?,1,1,256],[1,3,256,512]。

为了进一步调试,我使用 keras model.summary() 打印了整个网络。附上图片。我有两个担忧。

  1. 为什么我会收到负尺寸错误?
  2. 我已经看到输出形状中的第二个参数在 conv1d_7 层中变为 2,并且无法进行进一步的减法。什么是第二个参数?我经历过这个文档中我发现第二个参数是使用下面的公式(Height -Kernel Size + 1)得到的,表示窗口将滑过数据的步数。在我的情况下,内核大小是 3,我对高度感到困惑。该文件解释说“高度是输入网络的一个数据集的长度”。长度是指输入特征的数量,还是批量大小*输入特征的数量?如何在第一层的输出形状中计算 11250。下面是我的代码(我能够计算层的其余部分的参数,只有第二个参数令人困惑,以前的帖子解释了如何计算参数而不是数据的长度)。
  3. 对于每个样本如此巨大的特征(39249)并且只有大约 4k 个实例,哪种深度学习算法可能对准确分类有用?

任何帮助表示赞赏。谢谢。

model = Sequential()
 model.add(Conv1D(filters = 8, kernel_size=3, strides=3, activation='relu', input_shape=(n_timestamps,n_features)))

 model.add(Conv1D(filters=16, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))

 model.add(Conv1D(filters=32, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))

 model.add(Conv1D(filters=64, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))
 model.add(Conv1D(filters=64, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))

 model.add(Conv1D(filters=128, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=128, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=4,strides=3))
 print(model.summary())

 model.add(Conv1D(filters=256, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=256, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=256, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))
 print(model.summary())

 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))
 print(model.summary())

 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(Conv1D(filters=512, kernel_size=3, strides=3, activation='relu'))
 model.add(MaxPooling1D(pool_size=2,strides=2))

 model.add(Flatten())
 model.add(Dense(4096, activation='relu'))
 #model.add(Dropout(0.5))
 model.add(Dense(4096, activation='relu'))
 #model.add(Dropout(0.5))
 model.add(Dense(n_outputs, activation='softmax'))
 print(model.summary())

在此处输入图像描述

4

2 回答 2

1

1-这里我们有一个问题,每层的步幅 = 3。它的意思是在每个卷积过滤器之后,feather_size 更改为 feather_size/3 以及它快速减小你的 feather_size 的原因。我建议你减少过滤器的步幅。例如 strides = 1 似乎合适。

2-作为一个通用公式,您可以计算每次转换后输出羽毛的大小。按 ((feather_size - kernel_size)/stride) + 1 过滤

最后,关于keras中卷积滤波器各个参数的更多描述,可以参考https://keras.io/layers/convolutional/

于 2020-03-13T21:04:40.343 回答
1

1)任何减少输出特征图的操作,都将是负维度错误的罪魁祸首。通常,它是由于“有效”填充、池化或跨步而发生的。

“有效” = 没有填充:

   inputs:         1  2  3  4  5  6  7  8  9  10 11 (12 13)
                  |________________|                dropped
                                 |_________________|

“POOLING” = 2x2 max-pooling,从 2by2 窗口中只取 1 个最大值,所以每次应用输出形状都会减半。

由于这些操作会缩小特征图的形状,因此有可能在一层中,特征图太小,甚至小于单个内核的大小,因此您不能再应用这些操作,因此这个错误。

2)您使用了高步幅值,因此特征图的长度下降得更快。您可以关注任何博客以了解如何计算每个参数,https://towardsdatascience.com/understanding-and-calculating-the-number-of-parameters-in-convolution-neural-networks-cnns-fc88790d530d

3) 您可以简单地减少 Dense 或 FC 层中的神经元数量。尝试使用较小的单位,例如 512 而不是 4096,看看准确性如何下降。添加一些批规范层并增加 dropout,以免发生过度拟合。

于 2020-03-16T11:52:53.810 回答