【问题标题】:Keras: Get the max values from a model output in a matrixKeras:从矩阵中的模型输出中获取最大值
【发布时间】:2020-05-11 21:51:29
【问题描述】:

不太确定为这个问题命名的最佳方式是什么,但我想将模型的输出处理为另一层的输入。我目前正在下面这样做,但想稍微更新一下信息。为了简单起见,我简化了模型。假设我们输入5x59 通道,其输出是5x56 通道和5x52 通道。

我的问题是我想处理model_output1,并获取每个通道中的最大值,并且只有 1 和 0(作为第二个模型的输入之一)。

例如,为了简单起见,假设我们有一个带有 3 个通道的 2x2。

[[[0, 1],
  [9, 3]]

 [[2, 5],
  [5, 4]]

 [[4, 2],
  [8, 7]]]

我想将其仅转换为 0 和 1,其中 1 表示相对于通道轴的最大值。所以对于上面的例子,我想得到:

[[[0, 0],
  [1, 0]]

 [[0, 1],
  [0, 0]]

 [[1, 0],
  [0, 1]]]

我尝试将model_output1 转换为带有.eval().numpy() 的numpy 数组,但我不断收到错误消息。我正在使用tensorflow-gpu 2.1.0。如果我可以将它转换为 numpy,我知道如何使用 numpy 来实现。

另一种解决方案是只使用 2 个单独的模型。我可以在哪里使用 .predict 获得model_output1,然后对其进行操作以获得我想要的并将其输入到第二个模型。但不确定这是否同样有效。

总而言之,我怎样才能将张量 model_output1 操作为我想要的格式?是否可以使用一些 tf.math 函数来完成它,而不将其转换为 numpy 数组?如果没有,我怎样才能将它转换为 numpy 数组而不抛出任何错误?或者我最好的选择是拥有 2 个不同的模型,然后在 .predict 之后操作第一个输出并将其处理为我想要的输入?

from keras.models import Model
from keras.layers import Dense, Conv2D, Input
from keras.layers.merge import concatenate
from keras.optimizers import Adam
import tensorflow as tf
import numpy as np

def build_model():
    model_input = Input(shape=(5, 5, 9))

    input_hidden = Conv2D(8, kernel_size=3, activation='relu', padding='same')(model_input )
    model_output1 = Dense(6, activation='softmax')(input_hidden)

    input_hidden2 = concatenate(inputs=[model_input, model_output1], axis=3)
    model_output2 = Dense(2, activation='softmax')(input_hidden2 )

    model = Model(inputs=model_input, outputs=[model_output1 , model_output2 ])

    model.compile(loss='mse', optimizer=Adam(lr=0.001))

    return model

模型总结:

Model: "model_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 5, 5, 9)      0                                            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 5, 5, 8)      656         input_1[0][0]                    
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 5, 5, 6)      54          conv2d_1[0][0]                   
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 5, 5, 15)     0           input_1[0][0]                    
                                                                 dense_1[0][0]                    
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 5, 5, 2)      32          concatenate_1[0][0]              
==================================================================================================
Total params: 742
Trainable params: 742
Non-trainable params: 0
__________________________________________________________________________________________________

【问题讨论】:

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


    【解决方案1】:

    我猜很简单,你的问题是给定一个形状为 (B, m, n, c) 的层输出,设计一个小模块给我输出具有相同形状但张量中的所有内容都是 0 或 1 (根据您的标准)。不需要的模型部分可以完全忽略。

    您可以在模型中使用所有 tensorflow 后端函数。这是我设计的一个简单模块:

    1. 输入层为(2,2,3)

    2. 取通道中输入的最大值(轴 = -1),得到输出形状 (2,2)

    3. 展开最大输出的维数并拼接得到与输入(2,2,3)形状相同的矩阵

    4. 然后,我们将 +1 添加到输入并从中减去连接的最大张量。

    5. 它将为我们提供与输入 (2,2,3) 形状相同的张量,但通道最大值的每个位置现在都将包含 1,而其他所有值将是 - 或 0。

    6. 最后,我们应用relu 激活来获得所需的输出。

    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.layers import *
    from tensorflow.keras.models import *
    
    ip = Input((2,2,3))
    mx = tf.keras.backend.max(ip, axis = -1)
    a1 = tf.expand_dims(mx, -1)
    cat = Concatenate(axis = -1)([a1, a1, a1])
    ip_add1 = tf.math.add(ip, 1)
    sub = Subtract()([ip_add1, cat])
    neg2zero = Activation('relu')(sub)
    
    model = Model(ip, neg2zero)
    
    x = np.transpose(np.array([
      [[0, 1],
      [9, 3]],
    
     [[2, 5],
      [5, 4]],
    
     [[4, 2],
      [8, 7]]], dtype = np.float32)) # your matrix need to be transposed as it had wrong order
    
    print(x)
    print(x.shape)
    y = model(x)
    print(y)
    

    输出:

    [[[0 2 4]
      [9 5 8]]
    
     [[1 5 2]
      [3 4 7]]]
    (2, 2, 3)
    WARNING:tensorflow:Model was constructed with shape (None, 2, 2, 3) for input Tensor("input_20:0", shape=(None, 2, 2, 3), dtype=float32), but it was called on an input with incompatible shape (2, 2, 3).
    tf.Tensor(
    [[[0. 0. 1.]
      [1. 0. 0.]]
    
     [[0. 1. 0.]
      [0. 0. 1.]]], shape=(2, 2, 3), dtype=float32)
    

    【讨论】:

    • 当我尝试使用'from keras.layers import Input、Concatenate、Subtract、Activation'声明的解决方案时,我收到错误'AttributeError:'NoneType'对象在行中没有属性'_inbound_nodes': '模型 = 模型(ip,neg2zero)'
    • 请使用tensorflow.keraskeras 已经有很多错误,在与tf 合并后很快就会过时。另外,您清楚地提到,您使用的是tensorflow 2.0
    • 啊,好吧,我不知道。那确实解决了这个问题,很抱歉造成混乱。但是现在我收到一个错误: ValueError: Inconsistent values for attr 'T' DT_INT32 vs. DT_FLOAT while building NodeDef 'Max' using Op 输出:T; attr=keep_dims:bool,default=false; attr=T:type,allowed=[DT_FLOAT, DT_DOUBLE, DT_INT32, DT_UINT8, DT_INT16, ..., DT_UINT16, DT_COMPLEX128, DT_HALF, DT_UINT32, DT_UINT64]; attr=Tidx:type,default=DT_INT32,allowed=[DT_INT32, DT_INT64]>' for line 'y = model(x)'
    • 我在 google colab 上运行了我的代码,它的 tensorflow 版本为 2.2.0-rc4,你在运行我的确切代码时遇到错误?
    • @user1179317,是的,我能够重现 tensorflow 2.1 中的错误,我修复了代码。立即检查。
    猜你喜欢
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多