【问题标题】:Keras give input to intermediate layer and get final outputKeras 给中间层输入并得到最终输出
【发布时间】:2019-03-18 21:28:55
【问题描述】:

我的模型是一个简单的全连接网络,如下所示:

inp=Input(shape=(10,))
d=Dense(64, activation='relu')(inp)
d=Dense(128,activation='relu')(d)
d=Dense(256,activation='relu')(d)     #want to give input here, layer3
d=Dense(512,activation='relu')(d)
d=Dense(1024,activation='relu')(d)
d=Dense(128,activation='linear')(d)

所以,在保存模型后,我想为第 3 层提供输入。我现在正在做的是:

model=load_model('blah.h5')    #above described network
print(temp_input.shape)        #(16,256), which is equal to what I want to give

index=3
intermediate_layer_model = Model(inputs=temp_input,
                                 outputs=model.output)

End_output = intermediate_layer_model.predict(temp_input)

但它不起作用,即我收到不兼容输入等错误,输入应该是元组等。错误消息是:

raise TypeError('`inputs` should be a list or tuple.') 
TypeError: `inputs` should be a list or tuple.

有什么方法可以在网络中间传递我自己的输入并获取输出,而不是在开始时提供输入并从结尾获取输出?任何帮助将不胜感激。

【问题讨论】:

  • 请包含输入不兼容的错误信息。
  • 我现在已经编辑了这个问题,请告诉我解决这个问题的方法。
  • @Asim 问题标题和描述是不同的东西:你在标题中提到你想给一个中间层输入并得到模型的输出,而在问题描述中,您试图获取模型的中间层的输出。确定需要哪一个,然后请相应地编辑您的问题。
  • 我做错了,我已经编辑了问题。我希望将输入提供给中间层并从最后获得输出。

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


【解决方案1】:

首先,您必须了解在 Keras 中,当您在输入上应用层时,a new node is created inside this layer 连接输入和输出张量。每层可能有多个节点,将不同的输入张量连接到它们对应的输出张量。为了构建模型,遍历这些节点并创建模型的新图,其中包含从输入张量到达输出张量所需的所有节点(即,您在创建模型时指定:model = Model(inputs=[...], outputs=[...])

现在您想输入模型的中间层并获取模型的输出。由于这是一条新的数据流路径,我们需要为对应于这个新计算图的每一层创建新节点。我们可以这样做:

idx = 3  # index of desired layer
input_shape = model.layers[idx].get_input_shape_at(0) # get the input shape of desired layer
layer_input = Input(shape=input_shape) # a new input tensor to be able to feed the desired layer

# create the new nodes for each layer in the path
x = layer_input
for layer in model.layers[idx:]:
    x = layer(x)

# create the model
new_model = Model(layer_input, x)

幸运的是,您的模型由一个分支组成,我们可以简单地使用 for 循环来构建新模型。但是,对于更复杂的模型,这样做可能并不容易,您可能需要编写更多代码来构建新模型。

【讨论】:

    【解决方案2】:

    这是实现相同结果的另一种方法。最初创建一个新的输入层,然后将其连接到较低的层(带有权重)。

    为此,首先重新初始化这些层(具有同名)并重新加载相应的权重父模型使用

    new_model.load_weights("parent_model.hdf5", by_name=True)

    这将从父模型加载所需的权重。只需确保事先正确命名图层即可。

    idx = 3  
    input_shape = model.layers[idx].get_input_shape_at(0) layer
    
    new_input = Input(shape=input_shape)
    
    d=Dense(256,activation='relu', name='layer_3')(new_input)
    d=Dense(512,activation='relu', name='layer_4'))(d)
    d=Dense(1024,activation='relu', name='layer_5'))(d)
    d=Dense(128,activation='linear', name='layer_6'))(d)
    
    new_model = Model(new_input, d)
    new_model.load_weights("parent_model.hdf5", by_name=True)
    

    此方法适用于具有多个输入或分支的复杂模型。您只需为所需层复制相同的代码,连接新输入并最终加载相应的权重。

    【讨论】:

      【解决方案3】:

      您可以轻松地为此目的使用 keras.backend.function:

      import numpy as np
      from tensorflow.keras.layers import Input, Dense
      from tensorflow.keras.models import Model
      from tensorflow.keras import backend as K
      
      inp=Input(shape=(10,))
      d=Dense(64, activation='relu')(inp)
      d=Dense(128,activation='relu')(d)
      d=Dense(256,activation='relu')(d)     #want to give input here, layer3
      d=Dense(512,activation='relu')(d)
      d=Dense(1024,activation='relu')(d)
      d=Dense(128,activation='linear')(d)
      
      model = Model(inp, d)
      
      
      foo1 = K.function(
          [inp],
          model.layers[2].output
      )
      
      foo2 = K.function(
          [model.layers[2].output],
          model.output
      )
      
      
      X = np.random.rand(1, 10)
      X_intermediate = foo1([X])
      print(np.allclose(foo2([X_intermediate]), model.predict(X)))
      

      对不起,丑陋的函数命名 - 尽力而为)

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,建议的解决方案对我有用,但我正在寻找更明确的东西,所以这里供将来参考:

        d1 = Dense(64, activation='relu')
        d2 = Dense(128,activation='relu')
        d3 = Dense(256,activation='relu')
        d4 = Dense(512,activation='relu')
        d5 = Dense(1024,activation='relu')
        d6 = Dense(128,activation='linear')
        
        inp = Input(shape=(10,))
        
        x = d1(inp)
        x = d2(x)
        x = d3(x)
        x = d4(x)
        x = d5(x)
        x = d6(x)
        
        full_model = tf.keras.Model(inp, x)
        full_model.summary()
        
        intermediate_input = Input(shape=d3.get_input_shape_at(0)) # get shape at node 0
        x = d3(intermediate_input)
        x = d4(x)
        x = d5(x)
        x = d6(x)
        partial_model = tf.keras.Model(intermediate_input, x)
        partial_model.summary()

        参考: https://keras.io/guides/functional_api/#shared-layers

        【讨论】:

          猜你喜欢
          • 2017-07-14
          • 1970-01-01
          • 2019-01-27
          • 1970-01-01
          • 2017-03-01
          • 2019-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多