繁体   English   中英

Keras 函数式 API 多输入模型

[英]Keras Functional API Multiple Input Model

我正在尝试在 Keras 中使用以下结构使用 Functional API 创建多输入模型:

多输入模型

共有三个输入: Team_1_InTeam_2_InHome_In 其中Team_1_InTeam_2_In通过Embedding层,然后BatchNormalizationFlatten层。 问题是当我尝试在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM