我正在使用tf.keras.applications.efficientnet_v2.EfficientNetV2L
模型,我想編輯模型的最后一層以使模型成為回歸和分類層。但是,我不確定如何編輯此模型,因為它不是線性順序模型,因此我不能這樣做:
for layer in model.layers[:-2]:
model.add(layer)
因為模型的某些層有多個輸入。除了最后一層之外,有沒有辦法保留模型,這樣模型會在最后一層之前發散?
efficentnet[:-2]
|
|
/ \
/ \
/ \
output1 output2
uj5u.com熱心網友回復:
要使功能模型具有分類層和回歸層,您可以按如下方式更改模型。請注意,有多種方法可以實作這一點,這是其中之一。
import tensorflow as tf
from tensorflow import keras
prev_model = keras.applications.EfficientNetV2B0(
input_tensor=keras.Input(shape=(224, 224, 3)),
include_top=False
)
接下來,我們將撰寫我們預期的頭部層,如下所示。
neck_branch = keras.Sequential(
[
# we can add more layers i.e. batch norm, etc.
keras.layers.GlobalAveragePooling2D()
],
name='neck_head'
)
classification_head = keras.Sequential(
[
keras.layers.Dense(10, activation='softmax')
],
name='classification_head'
)
regression_head = keras.Sequential(
[
keras.layers.Dense(1, activation=None)
],
name='regression_head'
)
現在,我們可以構建所需的模型。
x = neck_branch(prev_model.output)
output_a = classification_head(x)
output_b = regression_head(x)
final_model = keras.Model(prev_model.inputs, [output_a, output_b])
測驗
keras.utils.plot_model(final_model, expand_nested=True)
# OK
final_model(tf.ones(shape=(1, 224, 224, 3)))
# OK
更新
根據您的評論,
如果以前的模型是從
h5
檔案中匯入的,你將如何解決這個問題,因為我無法宣告頂層不包含在內?
如果我理解您的查詢,您有一個保存的模型(.h5
格式),其中包含頂層。在這種情況下,您沒有include_top
引數來排除頂部分支。因此,您可以做的是首先洗掉已保存模型的頂部分支。這里是如何,
# a saved model with top layers
prev_model = keras.models.load_model('model.h5')
prev_model_with_top_remove = keras.Model(
prev_model.input ,
prev_model.layers[-4].output
)
prev_model_with_top_remove.summary()
這prev_model.layers[-4].output
將洗掉頂部分支。最后,您將給出與我們可以得到的類似的輸出include_top=True
。檢查模型摘要以進行目視檢查。
uj5u.com熱心網友回復:
Keras 的功能 API 通過鏈接Keras張量(在此稱為 KTensor)而不是您日常的 TF 張量來作業。
因此,您需要做的第一件事是將適當形狀的 KTensor(使用 創建tf.keras.Input
)提供給原始模型。這將觸發前向鏈,促使模型的層產生自己的輸出 KTensor,這些輸出 KTensor 正確鏈接到輸入 KTensor。向前傳球后,
- 這些層將它們接收/生成的 KTensor 存盤在它們的
input
和output
屬性中。 - 模型本身還將存盤您提供給它的 KTensor 以及相應的最終輸出 KTensors和
inputs
屬性outputs
(注意 s)。
像這樣,
>>> from tensorflow.keras import Input
>>> from tensorflow.keras.layers import Dense
>>> from tensorflow.keras.models import Sequential, Model
>>> seq_model = Sequential()
>>> seq_model.add(Dense(1))
>>> seq_model.add(Dense(2))
>>> seq_model.add(Dense(3))
>>> hasattr(seq_model.layers[0], 'output')
False
>>> seq_model.inputs is None
True
>>> _ = seq_model(Input(shape=(10,))) # <--- Feed input KTensor to the model
>>> seq_model.layers[0].output
<KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'dense')>
>>> seq_model.inputs
[<KerasTensor: shape=(None, 10) dtype=float32 (created by layer 'dense_input')>]
一旦你獲得了這些內部 KTensor,一切都變得微不足道。要在最后兩層之前提取 KTensor 并將其轉發到兩個不同的分支以形成新的功能模型,請執行以下操作
>>> intermediate_ktensor = seq_model.layers[-3].output
>>> branch_1_output = Dense(20)(intermediate_ktensor)
>>> branch_2_output = Dense(30)(intermediate_ktensor)
>>> branched_model = Model(inputs=seq_model.inputs, outputs=[branch_1_output, branch_2_output])
請注意,您在第一步中輸入的 KTensor 的形狀必須符合接收它們的層的形狀要求。在我的示例中,輸入 KTensor 將被饋送到Dense(1)
層。由于Dense
需要在最后一維中定義輸入形狀,輸入 KTensor 可以是形狀,例如,(10,)
或,(None,10)
但不是(None,)
或(10, None)
。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/493876.html
上一篇:tensorflowhub示例在啟用Float16時拋出錯誤
下一篇:如何使用Scikit-Learn的RandomizedSearchCV和Tensorflow的ImageDataGenerator