【问题标题】:Unexpected output shape from a keras dense layerkeras 密集层的意外输出形状
【发布时间】:2022-01-15 02:11:16
【问题描述】:

我尝试创建一个只有一个隐藏层的最小 非卷积 NN 图像二元分类器(作为更复杂模型之前的实践):

def make_model(input_shape):
    inputs = keras.Input(shape=input_shape)
    x = layers.Dense(128, activation="ReLU")(inputs)
    outputs = layers.Dense(1, activation="sigmoid")(x)
    return keras.Model(inputs, outputs)
model = make_model(input_shape=(256, 256, 3))

它的model.summary() 显示

Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 256, 256, 3)]     0                                                                       
 dense (Dense)               (None, 256, 256, 128)     512                                                                    
 dense_1 (Dense)             (None, 256, 256, 1)       129                                                      
=================================================================
Total params: 641
Trainable params: 641
Non-trainable params: 0

由于dense_1 层只有一个神经元,我期望该层的输出形状为(None, 1)(即,表示预测的二进制标签的单个数字),但模型给出了(None, 256, 256, 1) .

我的模型设置有什么问题,如何才能正确设置?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    你的函数make_model有一个错误。

    def make_model(input_shape):
        inputs = keras.Input(shape=input_shape)
        x = layers.Dense(128, activation="ReLU")(x)
        outputs = layers.Dense(1, activation="sigmoid")(x)
        return keras.Model(inputs, outputs)
    

    你可能希望第二行是

    x = layers.Dense(128, activation="ReLU")(inputs)
    

    而不是

    x = layers.Dense(128, activation="ReLU")(x)
    

    不幸的是,x 存在于范围内,所以它没有抛出错误。

    【讨论】:

    • 嘿@Captain Trojan,是的,你是对的,哈哈……我的代码比这复杂一点,我在编辑我的代码以使其尽可能简洁时忘记重命名变量。 .我刚刚修改了我的问题来解决这个问题......
    【解决方案2】:

    如果你想使用输出形状(None, 1),你必须将你荒谬的大张量展平:

    import tensorflow as tf
    
    def make_model(input_shape):
        inputs = tf.keras.layers.Input(shape=input_shape)
        x = tf.keras.layers.Dense(128, activation="relu")(inputs)
        x = tf.keras.layers.Flatten()(x)
        outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)
        return tf.keras.Model(inputs, outputs)
    
    model = make_model(input_shape=(256, 256, 3))
    print(model.summary())
    

    【讨论】:

    • 你好@AloneTogether,感谢您的回答。刚刚试了,可以的。但是我对flatten()操作的必要性有点困惑——假设一个层只有一个节点,无论有多少节点可以向该层发送信号,该层应该只能输出一个标量信号。那么为什么必须使用明确的flatten() 呢?
    • 您的输入数据是 3D(不包括批量大小)并且您想要一维输出(同样不包括批量大小),这就是您需要 Flatten 层的原因。哦,顺便说一句,Dense 层仅应用于张量的最后一个维度。这就是为什么您在第一个 Dense 层中获得输出形状 (None, 256, 256, 128) 的原因。
    • 感谢@AloneTogether,我似乎与您在互联网上的评论中所说的相似。我不太明白他们的观点,所以我跳过了。猜猜我需要 RTFM 才能得到你在说什么。谢谢!
    • 我理解你的理论思想,当然,但这就是 Keras 的工作原理。
    • @AlexKong “那么为什么必须使用明确的 flatten() 呢?”因为将Dense 应用于非展平的 Conv2D 层也很有用,所以它作为 1x1 卷积工作,这有助于减少模型中的参数数量。此外,将Dense 应用于 2D 张量可以被认为是具有批量大小的简单 MLP。就是这样 - 将Dense 应用于张量仅在最后一个维度上执行全连接操作。
    猜你喜欢
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    相关资源
    最近更新 更多