ChatGPT解决这个技术问题 Extra ChatGPT

“Flatten”在 Keras 中的作用是什么?

我试图了解 Flatten 函数在 Keras 中的作用。下面是我的代码,它是一个简单的两层网络。它接收形状为 (3, 2) 的二维数据,输出形状为 (1, 4) 的一维数据:

model = Sequential()
model.add(Dense(16, input_shape=(3, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

x = np.array([[[1, 2], [3, 4], [5, 6]]])

y = model.predict(x)

print y.shape

这打印出 y 的形状为 (1, 4)。但是,如果我删除 Flatten 行,则会打印出 y 的形状为 (1, 3, 4)。

我不明白这一点。根据我对神经网络的理解,model.add(Dense(16, input_shape=(3, 2))) 函数创建了一个隐藏的全连接层,有 16 个节点。这些节点中的每一个都连接到每个 3x2 输入元素。因此,第一层输出的 16 个节点已经是“平坦的”。因此,第一层的输出形状应该是 (1, 16)。然后,第二层将其作为输入,输出形状为 (1, 4) 的数据。

因此,如果第一层的输出已经是“平坦的”并且形状为 (1, 16),我为什么需要进一步将其展平?

将其与 GlobalPooling stackoverflow.com/a/63502664/10375049 进行比较可能有助于理解 Flatten

C
Community

如果您阅读 Dense 的 Keras 文档条目,您将看到此调用:

Dense(16, input_shape=(5,3))

将产生一个具有 3 个输入和 16 个输出的 Dense 网络,这些网络将独立应用于 5 个步骤中的每一个。因此,如果 D(x) 将 3 维向量转换为 16 维向量,您将从层得到的输出将是一系列向量:[D(x[0,:]), D(x[1,:]),..., D(x[4,:])],形状为 (5, 16)。为了获得您指定的行为,您可以首先将您的输入 Flatten 输入到 15 维向量,然后应用 Dense

model = Sequential()
model.add(Flatten(input_shape=(3, 2)))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

编辑:有些人难以理解 - 这里有一张解释图片:

https://i.stack.imgur.com/Wk8eV.png


谢谢你的解释。只是为了澄清一下:使用 Dense(16, input_shape=(5,3),来自 16 个集合的每个输出神经元(并且,对于所有 5 个这些神经元集合),是否会连接到所有 (3 x 5 = 15) 个输入神经元?或者第一组16个中的每个神经元只连接到第一组5个输入神经元中的3个神经元,然后第二组16个中的每个神经元只连接到第二组5个输入中的3个神经元神经元等......我很困惑它是什么!
你有一个 Dense 层,它有 3 个神经元,输出 16 个,应用于 5 组 3 个神经元中的每一组。
喔好吧。我想要做的是将 5 个颜色像素的列表作为输入,我希望它们通过一个完全连接的层。所以input_shape=(5,3)表示有5个像素,每个像素有3个通道(R,G,B)。但是根据您所说的,每个通道都将单独处理,而我希望所有三个通道都由第一层的所有神经元处理。那么在开始时立即应用 Flatten 层会给我想要的吗?
带和不带 Flatten 的小图可能有助于理解。
好的,伙计们-我为您提供了一张图片。现在您可以删除您的反对票。
M
Mahesh Kembhavi

https://i.stack.imgur.com/lmrin.png


是的,但为什么需要它,这是我认为的实际问题。
p
prosti

短读:

展平张量意味着删除除一个之外的所有维度。这正是 Flatten 层所做的。

长读:

如果我们考虑创建的原始模型(带有 Flatten 层),我们可以得到以下模型摘要:

Layer (type)                 Output Shape              Param #   
=================================================================
D16 (Dense)                  (None, 3, 16)             48        
_________________________________________________________________
A (Activation)               (None, 3, 16)             0         
_________________________________________________________________
F (Flatten)                  (None, 48)                0         
_________________________________________________________________
D4 (Dense)                   (None, 4)                 196       
=================================================================
Total params: 244
Trainable params: 244
Non-trainable params: 0

对于这个总结,下一张图片有望对每一层的输入和输出大小提供更多的意义。

如您所见,Flatten 层的输出形状为 (None, 48)。这是提示。您应该阅读它 (1, 48)(2, 48) 或 ... 或 (16, 48) ... 或 (32, 48),...

实际上,该位置上的 None 表示任何批量大小。对于要召回的输入,第一个维度表示批量大小,第二个维度表示输入特征的数量。

Keras 中 Flatten 层的作用超级简单:

张量上的展平操作将张量重塑为具有等于张量中包含的元素数量的形状,不包括批量维度。

https://i.stack.imgur.com/IBt6j.jpg

注意:我使用 model.summary() 方法来提供输出形状和参数详细信息。


你说None表示任意batch size,但是为什么D16的输出shape也有None,这里的3不就是batch size吗?
A
AEngineer

我最近遇到了这个问题,它确实帮助我理解了:https://www.cs.ryerson.ca/~aharley/vis/conv/

所以有一个输入,一个 Conv2D、MaxPooling2D 等,Flatten 层位于最后,并准确显示它们是如何形成的,以及它们如何继续定义最终分类 (0-9)。


这很棒。这里还有更多。 cs.cmu.edu/~aharley/vis
P
Pratima Rathore

根据经验,网络中的第一层应该与数据的形状相同。例如,我们的数据是 28x28 的图像,28 层的 28 个神经元是不可行的,因此将 28,28 扁平化为 784x1 更有意义。我们不是自己编写所有代码来处理它,而是在开始时添加 Flatten() 层,稍后当数组加载到模型中时,它们会自动为我们展平。


r
roberto

Flatten 明确说明了如何序列化多维张量(通常是输入张量)。这允许(展平的)输入张量和第一个隐藏层之间的映射。如果第一个隐藏层是“密集”的(序列化)输入张量的每个元素将与隐藏数组的每个元素连接。如果不使用 Flatten,输入张量映射到第一个隐藏层的方式将是模棱两可的。


n
neural net lab

当您必须处理图像数据集等多维输入时,Keras flatten 类非常重要。 Keras.layers.flatten 函数将多维输入张量扁平化为一维,因此您可以对输入层进行建模并构建神经网络模型,然后将这些数据有效地传递到模型的每个神经元中。

您可以使用时尚 MNIST 数据集轻松理解这一点。该数据集中的图像为 28 * 28 像素。因此,如果您在 python 中打印第一张图像,您可以看到一个多维数组,我们确实无法将其输入到我们的深度神经网络的输入层。

print(train_images[0])

first image of fashion MNIST

为了解决这个问题,我们可以在将图像数据输入神经网络时将其展平。我们可以通过将这个多维张量转换为一维数组来做到这一点。在这个扁平化的数组中,现在我们有 784 个元素 (28 * 28)。然后我们可以创建具有 784 个神经元的输入层来处理传入数据的每个元素。

我们可以通过使用一行代码来完成这一切,有点……

keras.layers.flatten(input_shape=(28,28))

如果您需要了解其实际工作原理、训练模型并评估其准确性,您可以在 neural net lab 阅读完整教程。


请确保您在回答时遵守 self-promotionbehaviour 的规则 - 您必须在回答中披露您的从属关系。
你的意思是这个层通常相当于那两行重塑输入:xTrain = xTrain.reshape(xTrain.shape[0], -1) xTest = xTest.reshape(xTest.shape[0], -1)
M
Matt Allen

在这里,我想介绍 Flatten 函数的另一种替代方法。这可能有助于了解内部发生的情况。另一种方法增加了三个代码行。而不是使用

#==========================================Build a Model
model = tf.keras.models.Sequential()

model.add(keras.layers.Flatten(input_shape=(28, 28, 3)))#reshapes to (2352)=28x28x3
model.add(layers.experimental.preprocessing.Rescaling(1./255))#normalize
model.add(keras.layers.Dense(128,activation=tf.nn.relu))
model.add(keras.layers.Dense(2,activation=tf.nn.softmax))

model.build()
model.summary()# summary of the model

我们可以用

    #==========================================Build a Model
    tensor = tf.keras.backend.placeholder(dtype=tf.float32, shape=(None, 28, 28, 3))
    
    model = tf.keras.models.Sequential()
    
    model.add(keras.layers.InputLayer(input_tensor=tensor))
    model.add(keras.layers.Reshape([2352]))
model.add(layers.experimental.preprocessing.Rescaling(1./255))#normalize
    model.add(keras.layers.Dense(128,activation=tf.nn.relu))
    model.add(keras.layers.Dense(2,activation=tf.nn.softmax))
    
    model.build()
    model.summary()# summary of the model

在第二种情况下,我们首先创建一个张量(使用占位符),然后创建一个输入层。之后,我们将张量重塑为扁平形式。所以基本上,

Create tensor->Create InputLayer->Reshape == Flatten

Flatten 是一个方便的功能,所有这些都是自动完成的。当然,这两种方式都有其特定的用例。 Keras 提供了足够的灵活性来操作您想要创建模型的方式。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅