Keras初学者:最后一层的输出形状应该是什么?

2024-07-04 08:05:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我很难在CNN背后的数学问题上绞尽脑汁,以及我应该如何在神经网络的各个层之间修改输出形状。在

我正在尝试在kagglehttps://www.kaggle.com/c/carvana-image-masking-challenge上进行carvana图像掩蔽挑战。我可以在一个汽车的背景下,从其他的图像中识别出来。在

所以我的输入都是图像,宽度=959px,高度=640px。我的输入数组的形状是(159640959,3),其中159表示输入数组总共包含159个图像。 我创建的目标是包含640行和959列的矩阵(每个像素都有一个条目),使用布尔值来表示对应的像素是否是汽车/在汽车边界内。目标数据的形状是(159640959),其中159可能表示目标持有159个图像

我创建了一个结构过早的卷积网络(我的意思是,很少使用过滤器)。架构的代码在这里。在

  nn = Sequential()

  nn.add(Conv2D(8,(3,3), input_shape = (IMG_HEIGHT, IMG_WIDTH, 3),    activation = 'relu', padding = 'same'))
  nn.add(Conv2D(8, (3,3), activation='relu', padding='same'))
  nn.add(Dense(1, activation='softmax'))

Summary()显示以下内容:

^{pr2}$

我一直坚持的错误是。。。在

ValueError:检查目标时出错:预期稠密_1具有4个维度,但得到的数组形状为(159,640,959)

目前,我实际上不确定我将如何修改此代码以使其正常工作并克服此错误。我不明白最后一层应该有4个维度。根据Keras的总结,这个输出实际上有4个维度,但其中一个维度被标记为无。如果输出的形状不是(640959),就像每个目标图像一样。。。我真的不知道输出的形状应该是什么。 我只是很难把我之前所学的关于卷积网络的知识应用到实际的代码中。我无法克服这个错误,我目前正在努力想办法。有一些基本的东西我做得不正确。。。在

编辑:最初说这些图片的形状是440像素X 959像素。这是不正确的,它实际上是640像素X 959像素。我的打字很不方便。在


Tags: 代码图像网络add目标错误像素nn
1条回答
网友
1楼 · 发布于 2024-07-04 08:05:36

Dense上的documentation不是最清晰的,但从描述输入和输出形状的部分可以清楚地看到。在

Note: if the input to the layer has a rank greater than 2, then it is flattened prior to the initial dot product with kernel.

...

Input shape

nD tensor with shape: (batch_size, ..., input_dim). The most common situation would be a 2D input with shape (batch_size, input_dim).

Output shape

nD tensor with shape: (batch_size, ..., units). For instance, for a 2D input with shape (batch_size, input_dim), the output would have shape (batch_size, units).

这是非常令人困惑的,因为它讨论了高阶张量将如何首先被展平(这使得您认为{}的总体输出将是批处理中每个示例的纯标量值),但是正如您从{}打印输出所示,它保持了张量的相同中间维。在

因此,如果你给一个输入是(None, 640, 959, 8),这意味着{}将把最后一个维度作为一个完整的连接来处理,并将把内部维度指定的640x959个位置中的每一个单独的单元视为一个单独的输出神经元。。。在

如果你的网络是这样的:

nn = Sequential()
nn.add(Conv2D(8, (3,3), input_shape = (640, 959, 3), activation='relu', padding='same'))
nn.add(Conv2D(8, (3,3), activation='relu', padding='same'))
nn.add(Dense(1, activation='softmax'))

那么最终的输出形状将是

^{pr2}$

也就是说,640x959网格中的每个输出“像素”(i,j)被计算为上一层的点(i,j)处的8个不同卷积信道的密集组合。在

有多种方法可以实现相同的功能,例如将通道尺寸从8降到1的1x1卷积也会产生相同的输出形状,其层类似于

Conv2D(1, (1,1), activation='relu', padding='same')

或者您可以参考您正在进行的特定Kaggle竞赛的"naive Keras" example,它使用以下内容:

model = Sequential()
model.add( Conv2D(16, 3, activation='relu', padding='same', input_shape=(320, 480, 12) ) )
model.add( Conv2D(32, 3, activation='relu', padding='same') )
model.add( Conv2D(1, 5, activation='sigmoid', padding='same') )

除此之外,我们还有两个问题,即您为我们打印的代码中的数据维度不正确。在

一种情况是,您声明图像高度为440,但keras输出为640。在

另一个原因是最终的密集层在输出中有6个通道,但是您提供的相应代码只能导致1个通道。在

所以很可能您使用的代码和粘贴在这里的代码之间仍然存在一些不匹配,这使得我们无法看到维度问题的全部问题。在

例如,这个网络的丢失层应该将汽车位置像素的基本真实位掩码与最后一层的640x959Dense输出进行比较(一旦你解决了在输出中显示6个通道的奇怪问题)。在

但你报告的错误信息是

ValueError: Error when checking target: expected dense_1 to have 4 dimensions, but got array with shape (159, 640, 959)

这意味着这批目标数据可能需要被重塑成形状(159, 640, 959, 1)的张量,只是为了与来自Dense层的形状一致。在

相关问题 更多 >

    热门问题