在 TF 中将预训练模型与自定义模型相结合

时间:2021-07-03 22:24:58

标签: tensorflow machine-learning keras deep-learning computer-vision

我有一个简单的网络,我想通过将其与预训练模型(如 InceptionV3)相结合来增加其复杂性。但是,一旦我使用以下命令将它们连接在一起:

snn_model = Model(inputs=baseModel.input, outputs=model, name = 'snn')

我遇到了这个错误:

ValueError: Output tensors of a Functional model must be the output of a TensorFlow `Layer` (thus holding past layer metadata). Found: <tensorflow.python.keras.engine.functional.Functional object at 0x7f82d1804c10>

我的网络如下:

def build_siamese_model(inputShape, embeddingDim=48):

  # increase model complexity by adding Inception
  # make the network itself generate the embediings

  # specify the inputs for the feature extractor network
  inputs = Input(inputShape)

  # define the first set of CONV => RELU => POOL => DROPOUT layers
  x = Conv2D(64,(2,2), padding='same', activation='relu')(inputs)
  x = MaxPooling2D(pool_size=2)(x)
  x = Dropout(0.3)(x)

  # second set of CONV => RELU => POOL => DROPOUT layers
  x = Conv2D(64,(2,2), padding='same', activation='relu')(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Dropout(0.3)(x)

  # prepare the final outputs
  pooledOutput = GlobalAveragePooling2D()(x)
  outputs = Dense(embeddingDim)(pooledOutput)

  # build the model
  model = Model(inputs, outputs)

  # return the model to the calling function
  return model

我将我的网络与 InceptionV3 结合如下:

baseModel = InceptionV3(weights="imagenet", include_top=False, input_shape=(160, 160,3), input_tensor=Input(shape=(160, 160,3)))

snn_model = Model(inputs=baseModel.input, outputs=model, name = 'snn')

即使我尝试通过将 InceptionV3 输出作为自定义网络的输入在这些模型之间切换,我还是遇到了另一个错误:

ValueError: Negative dimension size caused by subtracting 2 from 1 for '{{node max_pooling2d_62/MaxPool}} = MaxPool[T=DT_FLOAT, data_format="NHWC", explicit_paddings=[], ksize=[1, 2, 2, 1], padding="VALID", strides=[1, 2, 2, 1]](Placeholder)' with input shapes: [?,1,1,64].

因此,我的想法是将自定义模型与预训练模型结合起来,以增加复杂性并获得更好的性能。

2 个答案:

答案 0 :(得分:0)

对迁移学习的简单谷歌搜索将 Transfer learning and fine-tuning 作为第一个结果。我建议你先阅读它,因为它正是你想要做的。

基本上,您将使用 InceptionV3,就像在 build_siamese_model 函数中使用普通层一样,返回整个模型。像这样的事情会做:

# specify the inputs for the feature extractor network
inputs = Input(inputShape)

# define the first set of CONV => RELU => POOL => DROPOUT layers
x = baseModel(inputs) # initialized from InceptionV3
x = Conv2D(64,(2,2), padding='same', activation='relu')(x)
x = MaxPooling2D(pool_size=2)(x)
x = Dropout(0.3)(x)
# the rest of your code ...

同样,您应该阅读文档以了解如何正确实例化预训练模型并处理批量归一化层

答案 1 :(得分:0)

第一个错误是由于指定的输出不正确。您应该定义模型的输出,即层的输出。所以为了解决第一个错误,修改后的代码,应该是这样的:

snn_model = Model(inputs=baseModel.input, outputs=model.output, name = 'snn')

第二个错误表明,您正在通过模型层缩小输入张量,直到达到 (1,1) 大小。然后它不能更进一步,因为每个 Conv2DMaxPooling 层都可以使输入尺寸更小,并且它会在中间层的某处变为负值。因此,尝试移除一些层或架构,或者尝试提供更大的输入尺寸,以避免在中间层达到 (1,1) 张量。您可以使用 model.summary() 查看每个层的输出形状,以便找出输入张量在整个层中的旅程。