簡體   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