Keras将输入提供给中间层并获得最终输出

时间:2018-10-14 06:19:35

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

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

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.

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

4 个答案:

答案 0 :(得分:3)

首先,当您在输入a new node is created inside this layer上施加一层连接输入和输出张量的层时,必须在Keras中学习到这一点。每一层可以具有将不同的输入张量连接到其相应的输出张量的多个节点。为了构建模型,需要遍历这些节点并创建一个新的模型图,其中包括从输入张量(即在创建模型时指定的LOCK_DURATION中指定到达输出张量的所有节点)。

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

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) 循环来构建新模型。但是,对于更复杂的模型,这样做可能并不容易,您可能需要编写更多代码来构建新模型。

答案 1 :(得分:1)

这里是获得相同结果的另一种方法。首先创建一个新的输入层,然后将其连接到较低的层(具有权重)。

为此,首先重新初始化这些图层(具有相同的名称),然后重新加载相应的权重 >使用

父模型

  

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)

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

答案 2 :(得分:0)

我遇到了同样的问题,建议的解决方案对我有用,但是我正在寻找更明确的内容,因此在这里供以后参考:

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

答案 3 :(得分:-1)

您可以轻松地为此使用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)))

很抱歉,函数命名很丑-做到最好)