如图1所示,我有3个模型,每个模型适用于一个特定的领域。
3个模型分别使用不同的数据集进行训练。
推理是连续的:
我试图通过python的多进程库来并行调用这3个模型,但它非常不稳定,不建议这样做。
我的想法是确保一次性完成这些:
由于这3个模型共享一个公共的预训练模型,因此我想创建一个具有多个输入和多个输出的模型。
如下图所示:
在推理过程中,我将调用一个模型,它将同时执行所有3个操作。
我看到KERAS的Functional API是可以的,但我不知道如何做到这一点。数据集的输入具有相同的维度。这些是(200,200,3)的图片。
如果任何人有一个共享公共结构的多输入多输出模型的例子,我都可以。
UPADE
下面是我的代码的例子,但是它返回了一个错误,因为layers. concatenate (...)
线传播了一个EfficientNet
模型没有考虑的形状。
age_inputs = layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3), name="age_inputs")
gender_inputs = layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3)
, name="gender_inputs")
emotion_inputs = layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3),
name="emotion_inputs")
inputs = layers.concatenate([age_inputs, gender_inputs, emotion_inputs])
inputs = layers.Conv2D(3, (3, 3), activation="relu")(inputs)
model = EfficientNetB0(include_top=False,
input_tensor=inputs, weights="imagenet")
model.trainable = False
inputs = layers.GlobalAveragePooling2D(name="avg_pool")(model.output)
inputs = layers.BatchNormalization()(inputs)
top_dropout_rate = 0.2
inputs = layers.Dropout(top_dropout_rate, name="top_dropout")(inputs)
age_outputs = layers.Dense(1, activation="linear",
name="age_pred")(inputs)
gender_outputs = layers.Dense(GENDER_NUM_CLASSES,
activation="softmax",
name="gender_pred")(inputs)
emotion_outputs = layers.Dense(EMOTION_NUM_CLASSES, activation="softmax",
name="emotion_pred")(inputs)
model = keras.Model(inputs=[age_inputs, gender_inputs, emotion_inputs],
outputs =[age_outputs, gender_outputs, emotion_outputs],
name="EfficientNet")
optimizer = keras.optimizers.Adam(learning_rate=1e-2)
model.compile(loss={"age_pred" : "mse",
"gender_pred":"categorical_crossentropy",
"emotion_pred":"categorical_crossentropy"},
optimizer=optimizer, metrics=["accuracy"])
(age_train_images, age_train_labels), (age_test_images, age_test_labels) = reg_data_loader.load_data(...)
(gender_train_images, gender_train_labels), (gender_test_images, gender_test_labels) = cat_data_loader.load_data(...)
(emotion_train_images, emotion_train_labels), (emotion_test_images, emotion_test_labels) = cat_data_loader.load_data(...)
model.fit({'age_inputs':age_train_images, 'gender_inputs':gender_train_images, 'emotion_inputs':emotion_train_images},
{'age_pred':age_train_labels, 'gender_pred':gender_train_labels, 'emotion_pred':emotion_train_labels},
validation_split=0.2,
epochs=5,
batch_size=16)
1条答案
按热度按时间bkhjykvo1#
我们可以在
tf. keras
中使用其出色的Functional API轻松做到这一点。在这里,我们将指导您如何使用Functional API构建不同类型(classification
和regression
)的multi-out。根据您的上一个图,您需要一个输入模型和三个不同类型的输出。为了演示,我们将使用
MNIST
,这是一个手写数据集。它通常是一个10类分类问题数据集。从中,我们将创建一个额外的2类分类器(数字是even
还是odd
)以及1回归部分(这是为了预测数字的平方,即对于图像输入9,它应该近似地给予它的平方)。数据集
因此,我们的训练对将是
xtrain
和[y_out_a, y_out_b, y_out_c]
,与上一个图相同。样板楼
让我们使用
tf. keras
的Functional API相应地构建模型。请参见下面的模型定义。MNIST
样本是28 x 28
灰度图像。因此我们的输入是以这种方式设置的。我猜您的数据集可能是RGB,因此相应地更改输入维度。需要注意的是,在模型定义过程中定义
out_a
、out_b
和out_c
时,我们设置了它们的name
变量,这一点非常重要。它们的名称分别为set'10cls'
、'2cls'
和'1rg'
。您也可以从上图(最后3个尾部)中看到这一点。编译并运行
现在,我们可以看到为什么
name
变量很重要。为了运行模型,我们需要首先使用正确的loss
函数,metrics
和optimizer
编译它。现在,如果你知道了,对于classification
和regression
问题,optimizer
可以是相同的,但对于loss
函数和metrics
应该改变。(2个分类和1个回归),我们需要为这些类型中的每一个设置适当的loss
和metrics
。请参见下面的操作。看,我们上面模型的每一个最后输出,在这里由它们的
name
变量表示。我们为它们设置了适当的编译。希望你理解这一部分。现在,是时候训练模型了。这就是最后一层的每个输出如何通过其关注的
loss
函数进行优化。仅供参考,有一件事要提,当.compile
模型时,您可能需要一个重要参数:loss_weights
-对不同模型输出的损失贡献进行加权。参见我的其他答案here。预测/推断
让我们看看一些输出。我们现在希望这个模型可以预测3事情:(1)是数字是什么,(2)它是偶数还是奇数,(3)它的平方值。
如果我们想快速检查模型的输出层
将这个
xtrain[0]
(我们知道5)传递给模型进行预测。更新
根据您的评论,我们可以扩展上述模型以接受多输入。我们需要改变一些东西。为了演示,我们将使用
mnist
数据集的train
和test
样本作为模型的多输入。接下来,我们需要修改上述模型的某些部分,以采用多输入。接下来,如果您现在绘图,您将看到新的图形。
现在,我们可以如下训练模型
现在,我们可以测试多输入模型并从中获得多输出。