Keras 有条件地将一个模型输出传递给另一个模型

Moh*_*ved 9 python machine-learning neural-network keras tensorflow

我正在尝试在 keras 中进行神经网络,它首先检查它是猫还是狗(基本模型)。

如果是狗,则通过另一个模型(sub-model-1)

如果它是一只猫,那么它会通过另一个模型(子模型 2)

子模型是专门训练的小模型,用于根据品种进行分类..所以子模型 1 会将狗分类为各种狗的品种。. 而 sub-model-2 会将猫分类为各种猫的品种。

我面临的问题是:我不知道如何添加条件层,这样如果基础模型有 500 万个神经元,每个子模型有 200 万-200 万个神经元。如果图像通过基础模型,那么它应该只通过 sub-model1 或 sub-model2.. 所以总共只有 700 万个神经元在将一张图像传递到最终输出。

任何帮助,参考,一切都将是可观的。

在此处输入图片说明

Min*_*ark 5

这是另一种解决方案,与此处列出的替代方案相比,它可以更快地训练、更快地运行并使用更少的 RAM、提供更好的性能并且更易于使用。

只需使用具有多个输出的单个模型:二进制输出(猫/狗)、猫品种输出(多类)和狗品种输出(多类)。在训练期间,您可以使用自定义损失函数来忽略与错误物种对应的损失(例如,忽略狗图像的猫品种输出)。

好处是:

  • 更快的训练:只需训练一个模型。
  • 更好的性能:在进行这样的多任务学习时,通常可以获得更好的性能。那是因为狗图像和猫图像有很多共同点,所以为两者训练一个单一的基础神经网络,然后在此基础上构建专门的网络是有帮助的。
  • 更少的 RAM 和更少的计算:我们不必通过两个 CNN(一个用于猫/狗检测器,一个用于品种),我们只需通过一个(基础网络)。这在很大程度上补偿了我们通过狗品种分类器所做的不必要的计算,即使猫/狗检测器说它是一只猫。
  • 更易于使用:只需对模型进行一次调用,即可立即获得所需的一切。此外,如果猫/狗检测器不太确定(例如它输出 50% 的概率),那么您至少可以为猫和狗提供合理的候选者。

这是一个工作示例。你只需要用你自己的数据替换。请注意,有三个标签:

  • 猫/狗:例如 [0, 1, 1, 0] 表示狗、猫、猫、狗
  • 猫品种:例如 [-1, 2, 0, -1] 表示非猫、2nd cat class、0th cat class、not-a-cat
  • 狗的品种:例如 [3, -1, -1, 1] 表示第 3 级狗,not-a-dog,not-a-dog,1st dog class
import numpy as np
import tensorflow as tf
from tensorflow import keras

np.random.seed(1)
tf.random.set_seed(1)

num_images = 200
num_cat_breeds = 10
num_dog_breeds = 15

X_train = np.random.random([num_images, 32, 32, 3])
y_breed = np.random.randint(num_cat_breeds + num_dog_breeds, size=num_images)
y_is_cat = y_breed < num_cat_breeds
y_cat_breed = np.where(y_is_cat, y_breed, -1)
y_dog_breed = np.where(y_is_cat, -1, y_breed - num_cat_breeds)

base_model = keras.Sequential([
    keras.layers.Conv2D(filters=32, kernel_size=3, activation="relu"),
    keras.layers.Flatten(),
])

model_is_cat = keras.Sequential([
    keras.layers.Dense(1, activation="sigmoid")
])

model_cat_breed = keras.Sequential([
    keras.layers.Dense(num_cat_breeds, activation="softmax")
])

model_dog_breed = keras.Sequential([
    keras.layers.Dense(num_dog_breeds, activation="softmax")
])

image_input = keras.layers.Input(shape=[32, 32, 3])
z = base_model(image_input)
is_cat = model_is_cat(z)
cat_breed = model_cat_breed(z)
dog_breed = model_dog_breed(z)
model = keras.Model(inputs=[image_input],
                    outputs=[is_cat, cat_breed, dog_breed])

def optional_crossentropy(y_true, y_pred):
    is_not_ignored = y_true != -1
    y_true_no_ignore = tf.where(is_not_ignored, y_true, 0)
    mask = tf.cast(is_not_ignored, tf.float32)
    return keras.losses.sparse_categorical_crossentropy(y_true_no_ignore, y_pred) * mask

model.compile(loss=["binary_crossentropy",
                    optional_crossentropy,
                    optional_crossentropy],
              optimizer="adam")
model.fit(X_train, [y_is_cat, y_cat_breed, y_dog_breed], epochs=2)

y_is_cat_pred, y_cat_breed_pred, y_dog_breed_pred = model.predict(X_train[:2])
print(y_is_cat_pred)
print(y_cat_breed_pred)
print(y_dog_breed_pred)
Run Code Online (Sandbox Code Playgroud)