Keras 向中间层提供输入并获得最终输出
Keras give input to intermediate layer and get final output
我的模型是一个简单的全连接网络,如下所示:
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.
有什么方法可以在网络中间传递我自己的输入并获得输出,而不是在开始时提供输入并从末尾获得输出?任何帮助将不胜感激。
首先,您必须了解在 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
循环来构建新模型。但是,对于更复杂的模型,这样做可能并不容易,您可能需要编写更多代码来构建新模型。
这是实现相同结果的另一种方法。最初创建一个新的输入层,然后将其连接到较低层(具有权重)。
为此,首先重新初始化这些层(使用同名)和重新加载 来自 父模型 的相应 权重 使用
new_model.load_weights("parent_model.hdf5", by_name=True)
这将从父级加载所需的权重 model.Just 确保事先正确命名图层。
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)
此方法适用于具有多个输入的复杂模型,或者branches.You只需为所需层复制相同的代码,连接新的输入并最终加载相应的权重。
您可以轻松地使用 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)))
抱歉函数命名丑陋 - 尽力而为)
我遇到了同样的问题,建议的解决方案对我有用,但我正在寻找更明确的东西,所以这里供将来参考:
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()
我的模型是一个简单的全连接网络,如下所示:
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.
有什么方法可以在网络中间传递我自己的输入并获得输出,而不是在开始时提供输入并从末尾获得输出?任何帮助将不胜感激。
首先,您必须了解在 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
循环来构建新模型。但是,对于更复杂的模型,这样做可能并不容易,您可能需要编写更多代码来构建新模型。
这是实现相同结果的另一种方法。最初创建一个新的输入层,然后将其连接到较低层(具有权重)。
为此,首先重新初始化这些层(使用同名)和重新加载 来自 父模型 的相应 权重 使用
new_model.load_weights("parent_model.hdf5", by_name=True)
这将从父级加载所需的权重 model.Just 确保事先正确命名图层。
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)
此方法适用于具有多个输入的复杂模型,或者branches.You只需为所需层复制相同的代码,连接新的输入并最终加载相应的权重。
您可以轻松地使用 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)))
抱歉函数命名丑陋 - 尽力而为)
我遇到了同样的问题,建议的解决方案对我有用,但我正在寻找更明确的东西,所以这里供将来参考:
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()