[英]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.