如何在序列中堆叠迁移学习模型



为了制作一个好的体系结构,我想将迁移学习模型一个堆叠在另一个之上。

我想堆叠的三个模型是:

  • VGG16
  • InceptionV3
  • Resnet50

因此,我定义了三个模型如下:

model_vgg = tf.keras.applications.VGG16(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)
model_inc = tf.keras.applications.inception_v3.InceptionV3(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)
model_res = tf.keras.applications.ResNet50(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)

大小设置为100

之后,我为它们中的每一个设置trainable=False

现在,我将如何按顺序堆叠这些模型,即我必须做出哪些更改,以便每个模型的输出形状与下一个模型的输入形状匹配?

model = tf.keras.Sequential([

model_vgg,
model_inc,
model_res,
tf.keras.layers.Flatten()

])

由于每个模型都有不同的输出形状,在将其输入下一个模型之前,您必须对每个模型进行整形,这可能会影响性能:

import tensorflow as tf
SIZE = 100
model_vgg = tf.keras.applications.VGG16(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)
model_inc = tf.keras.applications.inception_v3.InceptionV3(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)
model_res = tf.keras.applications.ResNet50(
weights='imagenet', 
include_top=False,
input_shape=(SIZE, SIZE, 3)
)
model_vgg.trainable = False
model_inc.trainable = False
model_res.trainable = False
model = tf.keras.Sequential([

model_vgg,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(SIZE*SIZE*3),
tf.keras.layers.Reshape((SIZE, SIZE, 3)),
model_inc,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(SIZE*SIZE*3),
tf.keras.layers.Reshape((SIZE, SIZE, 3)),
model_res,
tf.keras.layers.Flatten()

])
print(model(tf.random.normal((1, 100, 100, 3))).shape)

您还必须决定是否要在每个Dense层上使用非线性激活函数。哦,你也可以像这样使用每个模型的预处理方法:

model = tf.keras.Sequential([

tf.keras.layers.Lambda(lambda x: tf.keras.applications.vgg16.preprocess_input(x)),
model_vgg,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(SIZE*SIZE*3),
tf.keras.layers.Reshape((SIZE, SIZE, 3)),
tf.keras.layers.Lambda(lambda x: tf.keras.applications.inception_v3.preprocess_input(x)),
model_inc,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(SIZE*SIZE*3),
tf.keras.layers.Reshape((SIZE, SIZE, 3)),
tf.keras.layers.Lambda(lambda x: tf.keras.applications.resnet50.preprocess_input(x)),
model_res,
tf.keras.layers.Flatten()

])

我个人的建议是将输入输入到各个模型中,然后连接输出并运行其他下游操作:

inputs = tf.keras.layers.Input((SIZE, SIZE, 3))

vgg = tf.keras.layers.Lambda(lambda x: tf.keras.applications.vgg16.preprocess_input(x))(inputs)
vgg = tf.keras.layers.GlobalAvgPool2D()(model_vgg(vgg))
inc = tf.keras.layers.Lambda(lambda x: tf.keras.applications.inception_v3.preprocess_input(x))(inputs)
inc = tf.keras.layers.GlobalAvgPool2D()(model_inc(inc))
res = tf.keras.layers.Lambda(lambda x: tf.keras.applications.resnet50.preprocess_input(x))(inputs)
res = tf.keras.layers.GlobalAvgPool2D()(model_res(res))
outputs = tf.keras.layers.Concatenate(axis=-1)([vgg, inc, res])
model = tf.keras.Model(inputs, outputs)

最新更新