我正在尝试在喀拉拉邦的神经网络,该网络首先检查它是猫还是狗(基本模型)。
如果它是一条狗,那么它将通过另一个模型(sub-model-1)
如果它是猫,那么它会通过另一个模型(子模型2)
子模型是经过专门训练以根据品种进行分类的小模型。因此,子模型1会将狗归类为各种狗的品种。 。而子模型2会将猫分为各种猫的品种。
我面临的问题是: 我不知道如何添加条件层,因此如果基本模型具有500万个神经元,而每个子模型具有200万-200万个神经元..如果图像通过基本模型,则它应仅通过子模型1或子模型2 ..因此,在将一幅图像传递给最终输出时,总共只有700万个神经元在起作用。
任何帮助,参考,一切都会很明显。
答案 0 :(得分:1)
这是另一种解决方案,与此处列出的替代方案相比,它可以训练更快,运行更快并且使用更少的RAM,提供更好的性能并且更易于使用。
只需使用具有多个输出的单个模型:二进制输出(猫/狗),猫品种输出(多类)和狗品种输出(多类)。在训练过程中,您可以使用自定义损失功能来忽略与错误物种相对应的损失(例如,忽略狗图像的猫品种输出)。
好处是:
这是一个可行的例子。您只需要用自己的数据替换即可。请注意,共有三个标签:
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)
答案 1 :(得分:0)
方法1。
有一种方法可以基于先前的模型输出定义具有静态权重的Dense
图层,并且多个输出为0。但是,这不是通常的做法。
方法2。 而我们实际上正在做什么。
@staticmethod
def animal_breed(image):
# Just an example for getting some Models.
def get_model(inputs):
y = Dense(5)(image)
y = Dense(5, name='final-1')(y)
return Model(input=inputs, output=Dense(10)(y))
# Define Base Model
DogCatModel = get_model(
inputs=image)
result = DogCatModel.predict(image)
# Get Base model on condition. Or load your model
# from any other source.
def get_specific(value, model1, model2):
if value[0] > value[1]:
return model1
return model2
# Just a mock of inserting previous result
# In real works you wanted to inserted scalar results
# to the last layers(After CNN)
inputs = inputs[0][0] = result
SpecificModel = get_specific(
result, get_model(inputs), get_model(inputs)
)
return SpecificModel.predict(inputs)
为什么会这样呢?您可能会期望别的东西,但实际上,这是易于扩展的通用解决方案。您通常不会使用图层本身来组合不同的模型。 +还可以更轻松地配置/冻结设置。
答案 2 :(得分:0)
我建议您分别训练猫/狗二元分类模型以及猫品种和狗品种模型。然后,您可以使用自定义Keras模型进行推理。这是一个有效的示例,您只需要加载自己的数据集,并根据自己的喜好调整模型架构即可。
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 = y_breed[y_is_cat]
y_dog_breed = y_breed[~y_is_cat] - num_cat_breeds
model_cat_or_dog = keras.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=3, activation="relu"),
keras.layers.Flatten(),
keras.layers.Dense(1, activation="sigmoid")
])
model_cat_or_dog.compile(loss="binary_crossentropy", optimizer="adam")
model_cat_or_dog.fit(X_train, y_is_cat, epochs=2)
model_cat_breed = keras.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=3, activation="relu"),
keras.layers.Flatten(),
keras.layers.Dense(num_cat_breeds, activation="softmax")
])
model_cat_breed.compile(loss="sparse_categorical_crossentropy", optimizer="adam")
model_cat_breed.fit(X_train[y_is_cat], y_cat_breed, epochs=2)
model_dog_breed = keras.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=3, activation="relu"),
keras.layers.Flatten(),
keras.layers.Dense(num_dog_breeds, activation="softmax")
])
model_dog_breed.compile(loss="sparse_categorical_crossentropy", optimizer="adam")
model_dog_breed.fit(X_train[~y_is_cat], y_dog_breed, epochs=2)
class BreedModel(keras.Model):
def __init__(self, model_cat_or_dog, model_cat_breed, model_dog_breed, **kwargs):
super().__init__(**kwargs)
self.model_cat_or_dog = keras.models.clone_model(model_cat_or_dog)
self.model_cat_breed = keras.models.clone_model(model_cat_breed)
self.model_dog_breed = keras.models.clone_model(model_dog_breed)
def __call__(self, inputs):
y_proba_is_cat = self.model_cat_or_dog(inputs)
y_is_cat = tf.squeeze(y_proba_is_cat > 0.5)
cat_images = tf.boolean_mask(inputs, y_is_cat)
dog_images = tf.boolean_mask(inputs, ~y_is_cat)
Y_proba_cat_breed = self.model_cat_breed(cat_images)
Y_proba_dog_breed = self.model_dog_breed(dog_images)
return y_is_cat, y_proba_is_cat, Y_proba_cat_breed, Y_proba_dog_breed
num_test_images = 50
X_test = np.random.random([num_test_images, 32, 32, 3])
model = BreedModel(model_cat_or_dog, model_cat_breed, model_dog_breed)
y_is_cat, y_proba_is_cat, Y_proba_cat_breed, Y_proba_dog_breed = model(X_test)