[英]Keras functional api multiple input: The list of inputs passed to the model is redundant
[英]Keras Functional API Multiple Input Model
我正在尝试在 Keras 中使用以下结构使用 Functional API 创建多输入模型:
共有三个输入: Team_1_In
、 Team_2_In
、 Home_In
。 其中Team_1_In
和Team_2_In
通过Embedding
层,然后BatchNormalization
和Flatten
层。 问题是当我尝试在BatchNormalization
之后添加Flatten
层时出现此错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last) <ipython-input-46-8354b255cfd1> in <module>
15 batch_normalization_2 = BatchNormalization()(team_2_strength)
16
---> 17 flatten_1 = Flatten()(batch_normalization_1)
18 flatten_2 = Flatten()(batch_normalization_2)
19
~/conda/lib/python3.6/site-packages/keras/engine/topology.py in
__call__(self, inputs, **kwargs)
573 # Raise exceptions in case the input is not compatible
574 # with the input_spec specified in the layer constructor.
--> 575 self.assert_input_compatibility(inputs)
576
577 # Collect input shapes to build layer.
~/conda/lib/python3.6/site-packages/keras/engine/topology.py in assert_input_compatibility(self, inputs)
488 self.name + ': expected min_ndim=' +
489 str(spec.min_ndim) + ', found ndim=' +
--> 490 str(K.ndim(x)))
491 # Check dtype.
492 if spec.dtype is not None:
ValueError: Input 0 is incompatible with layer flatten_10: expected min_ndim=3, found ndim=2
我尝试使用BatchNormalization
层的轴参数,但没有帮助。 这是我的代码:
# create embedding layer
from keras.layers import Embedding
from keras.layers import BatchNormalization, Flatten, Dense
from numpy import unique
# Create an embedding layer
team_lookup = Embedding(input_dim=n_teams,
output_dim=1,
input_length=1,
name='Team-Strength')
# create model with embedding layer
from keras.layers import Input, Embedding, Flatten
from keras.models import Model
# Create an input layer for the team ID
teamid_in = Input(shape=(1,))
# Lookup the input in the team strength embedding layer
strength_lookup = team_lookup(teamid_in)
# Flatten the output
strength_lookup_flat = Flatten()(strength_lookup)
# Combine the operations into a single, re-usable model
team_strength_model = Model(teamid_in, strength_lookup_flat, name='Team-Strength-Model')
# Create an Input for each team
team_in_1 = Input(shape=(1,), name='Team-1-In')
team_in_2 = Input(shape=(1,), name='Team-2-In')
# Create an input for home vs away
home_in = Input(shape=(1,), name='Home-In')
# Lookup the team inputs in the team strength model
team_1_strength = team_strength_model(team_in_1)
team_2_strength = team_strength_model(team_in_2)
batch_normalization_1 = BatchNormalization()(team_1_strength)
batch_normalization_2 = BatchNormalization()(team_2_strength)
flatten_1 = Flatten()(batch_normalization_1)
flatten_2 = Flatten()(batch_normalization_2)
# Combine the team strengths with the home input using a Concatenate layer, then add a Dense layer
out = Concatenate()([flatten_1, flatten_2, home_in])
out = Dense(1)(out)
如错误所示,您需要Flatten层的 3D 张量:
ValueError: Input 0 is incompatible with layer flatten_10: expected min_ndim=3, found ndim=2
在代码的第一部分,您将输入传递给嵌入层,一切正常并且编译成功:
team_lookup = Embedding(input_dim=1,
output_dim=1,
input_length=1,
name='Team-Strength')
strength_lookup = team_lookup(teamid_in)
batch_normalization_1 = BatchNormalization()(strength_lookup)
strength_lookup_flat = Flatten()(batch_normalization_1)
team_strength_model = Model(teamid_in, strength_lookup_flat, name='Team-Strength-Model')
team_strength_model.compile(optimizer='adam', loss='categorical_crossentropy')
但是在代码的第二部分中,您将输入传递给team_strength_model
,它将张量展平,它们的形状转换为(batch, flatten)
。 当您将此 2D 张量传递给BatchNormalization
时,它会抛出这样的异常。
要解决此问题:
1)将输入传递给Embedding
层
2) 做BatchNormalization
3) 展平BatchNormalization
的输出
这是一个关于 Datacamp 练习的问题: https ://campus.datacamp.com/courses/advanced-deep-learning-with-keras-in-python/multiple-inputs-3-inputs-and-beyond?ex= 11
我在这里转载不是为了侵犯他们的IP,而是为了更清楚地解释它。 我对像 Datacamp 这样的网站(我经常使用它)的问题之一是,如果你不明白发生了什么,除了在 SO 上发帖之外,没有真正的追索权。
Datacamp 中的问题没有明确表述。 该练习介绍了集成模型; 在这里,一个模型根据常规赛数据预测两支篮球队之间的得分差异,另一个模型根据早期预测和新数据预测得分差异。
不幸的是,在练习中,这两个模型都只称为model
,它们的显示顺序是乱序的,而且练习中使用的实际模型从未与学生清楚地分享过。 哎呀。
这是第一个模型。 并不是说这与 OP 的模型不同,因为它使用的是嵌入层,而不是嵌入模型。 同样,Datacamp 练习对此并不清楚, Embedding
的性质在没有通知学生的情况下发生了变化。 它根据整数 id(哑)预测两支球队之间的比分差异,以及哪支球队是主场还是客场。
# Create an Input for each team
team_in_1 = Input(shape=(1,), name='Team-1-In')
team_in_2 = Input(shape=(1,), name='Team-2-In')
# Create an input for home vs away
home_in = Input(shape=(1,), name='Home-In')
# Create an embedding layer
team_lookup = Embedding(input_dim=n_teams,
output_dim=1,
input_length=1,
name='Team-Strength')
team_1_strength = team_lookup(team_in_1)
team_2_strength = team_lookup(team_in_2)
batch_normalization_1 = BatchNormalization(axis=1)(team_1_strength)
batch_normalization_2 = BatchNormalization(axis=1)(team_2_strength)
# flatten batch_normalization_1
flatten_1 = Flatten()(batch_normalization_1)
# flatten batch_normalization_2
flatten_2 = Flatten()(batch_normalization_2)
out = Concatenate()([flatten_1, flatten_2, home_in])
out = Dense(1)(out)
model = Model([team_in_1, team_in_2, home_in], out)
model.compile(optimizer="adam", loss="mean_absolute_error")
该模型然后适用于常规赛季数据:
model.fit([games_season["team_1"], games_season["team_2"], games_season["home"]],
games_season["score_diff"],
epochs=1,
verbose=True,
validation_split=0.1,
batch_size=2048)
...并用于预测不同数据集的得分差异:
# Predict
games_tourney['pred'] = model.predict(
[games_tourney["team_1"],
games_tourney["team_2"],
games_tourney["home"]])
现在将此数据集拆分为训练和测试。
games_tourney_train = games_tourney.loc[games_tourney["season"] < 2010]
games_tourney_test = games_tourney.loc[games_tourney["season"] >= 2010]
这是第二个模型,我没有具体原因将其称为preds_model
:
# Create an input layer with 3 columns
input_tensor = Input((3, ))
# Pass it to a Dense layer with 1 unit
output_tensor = Dense(1)(input_tensor)
# Create a model
preds_model = Model(input_tensor, output_tensor)
# Compile the model
preds_model.compile(optimizer="adam", loss="mean_absolute_error")
preds_model.fit(games_tourney_train[['home', 'seed_diff', 'pred']],
games_tourney_train['score_diff'],
epochs=1,
verbose=True)
最后,评估您的(第一个)集成模型:
# Evaluate the model on the games_tourney_test dataset
print(preds_model.evaluate(games_tourney_test[["home", "seed_diff", "pred"]],
games_tourney_test["score_diff"], verbose=False))
你的输出:
11.94
我怀疑那里有更直接的集成模型介绍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.