【问题标题】:TensorFlow, reshaping in CNNs confusionTensorFlow,在 CNN 的混乱中重塑
【发布时间】:2020-04-05 18:07:26
【问题描述】:

我已经多次看到这个疑问,但没有得到任何答案,至少我特别困惑,关于重塑如何工作以及为什么有必要。我会尽量简明扼要。

所以,我在 TensorFlow 文档中读到,当您实现 CNN 时,在将数据输入到卷积层之前,有必要对数据进行整形,因为卷积层采用 4D 张量,而不仅仅是一个列表元素(您下载的训练数据)。

Convolution-Pooling 过程的输出也是一个 4D 张量。它被送入 Flatten 层。现在...... Flatten 层,用于接收相同的列表元素,这些元素在将其传递给卷积之前需要重新整形。但是,为什么这两种方法都适用于 Flatten 层?它正在接收一个项目列表(不能直接馈送到卷积),现在正在接收一个 4D 张量。

那么如果没有卷积,Flatten 层会接收未重构的数据,如果有卷积池,它会接收 4D 张量,然后输出相同的东西?

我希望我足够清楚我的困惑是什么,并希望有人能够花一些时间来阐明我的疑问。

干杯!

【问题讨论】:

    标签: python tensorflow machine-learning keras conv-neural-network


    【解决方案1】:

    卷积神经网络 (CNN) 的输入数据将如下图所示。我们假设我们的数据是一组图像。

    您始终必须将 4D 数组作为 CNN 的输入。所以输入数据的形状为(batch_size, height, width, channels)。如果RGB 图像的通道为3greyscale 图像的通道为1

    CNN 的输出也是一个4D 数组。其中批量大小与输入批量大小相同,但图像的其他 3 个维度可能会根据我们使用的 filterkernel sizepadding 的值而改变

    我们看下面的代码

    import tensorflow as tf
    from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten
    
    model=tf.keras.models.Sequential()
    model.add(Conv2D(filters=64, kernel_size=1, input_shape=(10,10,3)))
    model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
    model.add(Flatten())
    model.add(Dense(10))
    model.summary()
    

    输出:

    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv2d (Conv2D)              (None, 10, 10, 64)        256       
    _________________________________________________________________
    max_pooling2d (MaxPooling2D) (None, 5, 5, 64)          0         
    _________________________________________________________________
    flatten (Flatten)            (None, 1600)              0         
    _________________________________________________________________
    dense (Dense)                (None, 10)                16010     
    =================================================================
    Total params: 16,266
    Trainable params: 16,266
    Non-trainable params: 0
    _________________________________________________________________
    

    认为它看起来像输入形状是3D,但你必须在拟合数据时传递一个4D数组,它应该像(batch_size, 10, 10, 3)。由于 input_shape 参数中没有批量大小值,我们可以在拟合数据时使用任何批量大小。

    Conv2DMaxPool2D 的输出形状分别为 (None, 10, 10, 64)(None, 5, 5, 64)。第一个维度代表批量大小,目前为None。因为网络事先并不知道批量大小。拟合数据后,None 将替换为您在拟合数据时提供的批量大小。

    我们可以简单地在另一个卷积层的顶部添加一个卷积层,因为卷积的输出维度与输入维度相同。

    我们通常在卷积层的顶部添加Dense 层来对图像进行分类。然而,输入数据到密集层2D 形状数组(batch_size, units)。而卷积层的输出是一个4D数组。

    因此,我们必须将从卷积层接收到的输出维度更改为2D 数组。我们可以通过在卷积层顶部插入Flatten 层来实现。展平层将图像的3 尺寸压缩为single 尺寸。现在我们只有一个2D 形状为(batch_size, squashed_size) 的数组,这对于密集层来说是可以接受的。

    注意:我们应该始终在网络中的Dense 层之前添加Flatten 层。

    如果是简单的网络,您可以使用Flatten 层开始网络,因为不需要卷积。

    model = tf.keras.models.Sequential([
      tf.keras.layers.Flatten(input_shape=(28, 28)),
      tf.keras.layers.Dense(128, activation='relu'),
      tf.keras.layers.Dense(10)
    ])
    

    【讨论】:

    • 非常感谢您的详尽回复!有些事情我仍然持怀疑态度。例如:对于一个简单的网络,Flatten 层的输入形状将是 [batch_size, height, width],对吗?在 CNN 的情况下,Flatten 层会得到一个 [batch_size, height, width, number_of_convolutions]...是这样吗?
    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多