【问题标题】:Tensorflow / Keras sigmoid on single output of dense layerTensorflow / Keras sigmoid 在密集层的单个输出上
【发布时间】:2021-11-16 01:24:45
【问题描述】:

我在 tensorflow 中有一个简单的 CNN 模型,它接收图像并预测 6 元素标签向量。因此,我的模式的最后一层是 Dense(6)。 Label[0] 应该是二进制的,而 Label[1:6] 是连续值的。因此,我想仅在输出的第一个节点上对输出层应用 sigmoid 激活,而其他 5 个输出保持原样。如何使用 tensorflow.keras 执行此操作?为简单起见,我的模型构建代码目前看起来像:

model = tf.keras.models.Sequential()
model.add(Reshape((image_size, image_size, 1), input_shape = (image_size, image_size))
model.add(Conv2D(8, **parameters))
model.add(BatchNormalization())
model.add(Activation('relu')
Model.add(MaxPool2D())
model.add(Flatten())
model.add(Dense(6))

如何添加到此以在最后一层的第一个索引上使用 sigmoid 激活?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    您可以定义一个简单的自定义Lambda 层并完全按照您的意愿行事。这是一个最初没有激活函数的示例。注意输出:

    import tensorflow as tf
    tf.random.set_seed(2)
    
    def custom_layer(tensor):
        activated_node = tf.nn.sigmoid(tensor[:, :1])
        return tf.concat([activated_node, tensor[:, 1:]], axis=1)
    
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(6))
    
    model(tf.random.uniform((2, 5)))
    
    <tf.Tensor: shape=(2, 6), dtype=float32, numpy=
    array([[-1.1554979 ,  0.29463094,  0.57452184,  0.40530735, -0.15730543,
             0.16329125],
           [-1.1518296 ,  1.2684885 ,  0.50156784,  1.2273686 ,  0.13656075,
            -0.7025717 ]], dtype=float32)>
    

    现在有了自定义Lambda 层,它将激活函数应用于张量中的第一个节点:

    import tensorflow as tf
    tf.random.set_seed(2)
    
    def custom_layer(tensor):
        activated_node = tf.nn.sigmoid(tensor[:, :1])
        return tf.concat([activated_node, tensor[:, 1:]], axis=1)
    
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(6))
    model.add(tf.keras.layers.Lambda(custom_layer, name="activation_layer"))
    
    model(tf.random.uniform((2, 5)))
    
    <tf.Tensor: shape=(2, 6), dtype=float32, numpy=
    array([[ 0.23948632,  0.29463094,  0.57452184,  0.40530735, -0.15730543,
             0.16329125],
           [ 0.24015504,  1.2684885 ,  0.50156784,  1.2273686 ,  0.13656075,
            -0.7025717 ]], dtype=float32)>
    

    您可以清楚地看到每个样本的第一个元素(我使用的是 batch_size=2)是如何在 0 和 1 之间挤压的。

    【讨论】:

      【解决方案2】:

      假设我们将模型的输出作为 pred,那么 pred 将是一个形状为 (1, 6) 的张量,因此为了实现您的目标,您可以执行以下操作:

      sigmoid_input = pred.numpy()[0][0]
      sigmoid_output = tf.keras.activations.sigmoid(sigmoid_input)
      

      因此,首先您需要将张量转换为 Numpy ndarray,然后仅访问张量的第一个元素。之后,我们按计划将保存该值的新变量 sigmoid_input 传递给 sigmoid。

      【讨论】:

      • 谢谢。我实际上希望 sigmoid 成为可训练模型的一部分,以便它使用 [0,1] 范围内的输出而不是 [-inf, inf] 进行学习。我可以使用 model.add() 以某种方式做到这一点吗?
      猜你喜欢
      • 2021-05-07
      • 2020-08-17
      • 2023-03-06
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2016-03-24
      • 2018-01-08
      • 1970-01-01
      相关资源
      最近更新 更多