我想使用具有张量流的Keras在两个现有网络(模型)A和B中创建一个新网络。新网络的架构就像这样
输入 - > A - > B - >输出
A的输出具有(15,500)的形状,B的输入具有(1000)的形状。我有一个转换方法,它接受形状(15,100)的输入并调用完全不同的网络(C)的预测,并返回形状为(1000)的输出。
我假设我必须引入一个Lambda图层,它将使用我的转换方法将A的输出转换为B所需的格式。但是,当我尝试这样做时,我收到错误
" TypeError:/:' Dimension'不支持的操作数类型并且'浮动' _"在转换方法中调用预测。
这是转换方法
def convert(x):
C = load_model("path/to/the/network/C.h5")
return C.predict(x)
我不确定这是否是正确的做法,如果是,那么为什么会出现这个错误。如果这不是正确的方式,那么,我的方法应该是什么。
Keras版本:2.0.1 Tensorflow版本:1.0.1
谢谢,
答案 0 :(得分:2)
我将假设您不是在尝试将C作为新网络的一部分进行训练(我们称之为D)。这就是我想象你想要的
A
|
(C) # transform step. a non-trainable keras model
|
B
|
out
请注意,变量名称来自原始答案部分中的示例。
更新,是原始回答中的代码仅使用dense_2
中的model_1
图层。
这不是你想要的,所以我去挖掘。而且很漂亮,答案很简单。
layer.trainable = False
将C的图层设置为无法训练。model_1(inp2)
以下是原始答案更新中的示例,为了证明C中的权重不可训练,我们将打印model_1.summary()
# let `model_1` be C in the diagram above.
from keras.models import Model
from keras.layers import (Lambda, Dense, Input)
inp = Input(shape=(5, ))
lam = Lambda(lambda x: x + 2, name='lamb')(inp)
den = Dense(1, name='dense')(lam) # this is the `model_1` output
model_1 = Model(inp, den)
# suppose we want an intermediate output from model_1
# (the `lam` layer for instance)
# we update the outputs and use that output in model2
model.outputs = [model.output, model.get_layer(name='lamb').output]
print(model.outputs)
# [<tf.Tensor 'dense_11/BiasAdd:0' shape=(?, 1) dtype=float32>,
# <tf.Tensor 'lamb_9/add:0' shape=(?, 5) dtype=float32>]
# now build D, since we can treat a model like a layer( awesome!)
# we can just let models A, B in the diagram above be layers
# (for this exmple) - nothing changes.
# But first set the layers of `model_1` to not be trainable:
print(model_1.summary()) # Trainable params: 6.0 - before
for l in model_1.layers:
l.trainable = False
print(model_1.summary()) # Trainable params: 0.0 - after
# ...then D is:
inp2 = Input(shape=(5, )) # imagine that this layer is model A
transform = model_1(inp2)[1] # this is (C) the transform step.
# Notice that we pulled out the lambda
# output by using the index into the
# `model_1's` outputs.
# carry on as normal
den2 = Dense(1)(transform) # imagine that this is B
model_2 = Model(inp2, den2)
model_2.compile(loss='mse', optimizer='adam')
model_2.summary()
# simulate data
X = np.random.randn(10, 5)
y = np.random.randn(10, 1)
# fit D
model_2.fit(X, y) # ... it trains!
一些注意事项:
我们不打算调用编译,因为我们不需要
配置培训模型。查看compile()
的文档字符串
或等同于keras docs
但是,如果我们使用keras.models.load_model
加载模型。
该模型已编译,但它不应该有任何影响,因为我们是
打算使用layer.trainable = False
。请参阅save()
原始答案
不是使用数组返回预测,而是抓住输出C的最后一层。
def convert(x):
# there is not need to load C in the lambda layer.
# load it somewhere outside of the training op.
# assuming you have C loaded...
return C.get_layer('dense_2')(x)
以下是此方法的一个简单示例:请注意,您必须制作 确保图层形状兼容。
你可以想象这是模式C
from keras.models import Model
from keras.layers import (Lambda, Dense, Input)
inp = Input(shape=(5,))
lam = Lambda(lambda x: x + 2, name='lamb')(inp)
den = Dense(1, name='dense')(lam) # this is the `model_` output
model_1 = Model(inp, den)
model_1.compile(loss='mse', optimizer='adam')
我们将抓取lam
图层的输出
并将其用作下面D中的转换步骤:
inp2 = Input(shape=(5, ))
# grab the 'dense' layer from `model_1`
sums = Lambda(lambda x: model_1.get_layer(name='dense')(x))(inp2)
den2 = Dense(1)(sums)
model_2 = Model(inp2, sums)
model_2.compile(loss='mse', optimizer='adam')
model_2.summary()