如何拼合任意输入形状的数据?

时间:2019-03-25 10:55:19

标签: python keras

我正在用Keras构建CNN,该CNN可以预测每个图像中13个关键点的坐标。我输入的图像各不相同,因此我的输入图层形状为(无,无,3)。我使用的是Inception模块,所以我使用的是功能API。现在,在为模型的最后一层编码时,我遇到了一个问题。据我所知,我的输出层将是Dense(26)层,因为我会将x和y坐标编码为矢量。我无法将输出层与前面的卷积层连接起来(由于张量尺寸)

x = Input(None, None, 3)
stage_1 = Conv2D(26, (1, 1))(x)
stage_1 = Dropout(0.3)(stage_1)
stage_2 = Conv2D(512, (1, 1))(x)
stage_2 = Dropout(0.3)(stage_2)
stage_2 = Activation('relu')(stage_2)
x = concatenate([stage_1, stage_2])
x = Lambda(lambda i: K.batch_flatten(i))(x)
outputs = Dense(26)(x)

我尝试包括Flatten层(但与任意输入形状不兼容),并且我尝试在Lambda层中使用K.batch_flatten()(这也不起作用)。我的问题是:是否有一个获得相似形状的输出层的不同方法((13,2)也可以,我只是在线上找到了其中输出层为密集层的模型)?我还尝试了GlobalAveragePooling2d(),但这大大降低了模型的准确性。另外,使用函数查找输出形状无效,请参见下文

stage_1 = Conv2D(26, (1, 1))(x)
stage_1 = Dropout(0.3)(stage_1)
stage_2 = Conv2D(512, (1, 1))(x)
stage_2 = Dropout(0.3)(stage_2)
stage_2 = Activation('relu')(stage_2)
x = concatenate([stage_1, stage_2])

def output_shape_batch(tensor_shape):
    print(tensor_shape)
    return (batch_size, tensor_shape[1] * tensor_shape[2] * tensor_shape[3])

x = Lambda(lambda i: K.batch_flatten(i), output_shape=output_shape_batch)(x)
outputs = Dense(26)(x)

我希望模型可以编译,但是会收到TypeErrors 错误是: TypeError:*:“ NoneType”和“ NoneType”的不受支持的操作数类型

1 个答案:

答案 0 :(得分:1)

据我所知,您所要求的几乎是不可能的。我将首先尝试解释原因,然后为您提供一些选择的替代方法。

神经网络通常期望输入固定大小的信息。由于该输入的每个值都将连接到权重,因此在初始化模型时需要输入的大小来计算权重数。通常无法输入大小不同的输入,因为这会改变权重的数量,并且尚不清楚在这种情况下应选择哪种权重/如何进行训练。
卷积层是一个例外。他们使用固定大小的内核,因此权重的数量不取决于输入大小,这就是keras支持这些“可变大小”输入的原因。但是,卷积层的输入大小会更改其输出大小。如果下一层也是对流层,这不是问题,但是当添加密集层时,输入大小必须固定。通常,全局池化层用于将可变大小的输出减少到固定大小。这样就可以毫无问题地添加致密层了。
由于您要预测图像中的坐标,因此全局平均对您而言不是一个好选择,因为它会破坏所有位置信息。因此,您可以考虑以下两种选择:

  1. 您可以在预处理期间将所有图像重新缩放为相同大小。
  2. 您可以为输入图像选择最大尺寸,并在图像上添加(零)填充以使它们都具有相同的尺寸。