0

我正在尝试训练一个称为 Siamese 模型的双流模型,该模型在其两个分支中的每一个上都有一个预训练的 resnet。我正在使用 Keras TF 后端。由于我的数据集非常小,我首先只解冻每个 resnet 的最后一层(avg_pool),将它们重命名为backbone_model1 和 2,然后将整个模型微调 30 个 Epoch。这是我如何做这部分的片段:

my_input = (320,320,3)
inputs1 = Input(my_input)
inputs2 = Input(my_input)
# the first branch operates on the first input images
backbone_model1 = ResNet50(include_top=False, pooling='avg')
backbone_model1.trainable = False
backbone_model1 = Model(inputs=backbone_model1.input, outputs=backbone_model1.get_layer('avg_pool').output, name='backbone_model1')
# the second branch operates on the second input images
backbone_model2 = ResNet50(include_top=False, pooling='avg')
backbone_model2.trainable = False
backbone_model2 = Model(inputs=backbone_model2.input, outputs=backbone_model2.get_layer('avg_pool').output, name='backbone_model2')
siamese1 = backbone_model1(inputs1)
siamese2 = backbone_model2(inputs2)
# mixing data and building the multi-input network
combined_siameses = concatenate([siamese1, siamese2])
# regression to calculate scores
output_final = Dense(1)(combined_siameses)
model = Model(inputs=[inputs1, inputs2], outputs=output_final)

如果我不解冻 resnet 的内层并仅通过微调两个 resnet 的 avg_pool 层来训练模型,那么一切都很好,我可以保存模型。但是,如果在 30 个 epoch 之后我想解冻所有内层,然后在微调所有层的同时再训练模型 30 个 epoch,我会收到此错误:

RuntimeError: Unable to create link (name already exists)
W tensorflow/core/kernels/data/generator_dataset_op.cc:103] Error occurred when finalizing GeneratorDataset iterator: Failed precondition: Python interpreter state is not initialized. The process may be terminated.
     [[{{node PyFunc}}]]

我开始意识到问题所在:两个 resnet 的层名称相同。所以难怪在第一个时代之后我得到这个“名字已经存在”的错误。在这个答案的帮助下,我将第二个 resnet 的名称更改为以下代码段:

trained_siamese_model = load_model(path_to_trained_siamese_model)
trained_siamese_model.trainable = True
for layer in trained_siamese_model.layers:
    if layer.name == 'backbone_model2':
       for layer_model2 in layer.layers:
          if layer_model2.name == 'input_3' or layer_model2.name == 'avg_pool':
             continue
          layer_model2._name = layer_model2.name + str("_2")

但是我仍然遇到该名称已经存在的相同错误,这是因为我没有在第二个 resnet 中重命名 avg_pool。但是,如果我重命名它,则会收到此错误:

ValueError: The target structure is of type `<class 'tensorflow.python.framework.ops.Tensor'>`
  Tensor("avg_pool/Mean_1:0", shape=(None, 2048), dtype=float32)
However the input structure is a sequence (<class 'list'>) of length 0.
  []
nest cannot guarantee that it is safe to map one to the other.
2021-11-23 18:38:13.210110: W tensorflow/core/kernels/data/generator_dataset_op.cc:103] Error occurred when finalizing GeneratorDataset iterator: Failed precondition: Python interpreter state is not initialized. The process may be terminated.
     [[{{node PyFunc}}]]

如果我重命名 input_3 层,它会抛出这个错误:

ValueError: The target structure is of type `<class 'tensorflow.python.framework.ops.Tensor'>`
  Tensor("input_3:0", shape=(None, None, None, 3), dtype=float32)
However the input structure is a sequence (<class 'list'>) of length 0.
  []
nest cannot guarantee that it is safe to map one to the other.
2021-11-24 02:18:22.525206: W tensorflow/core/kernels/data/generator_dataset_op.cc:103] Error occurred when finalizing GeneratorDataset iterator: Failed precondition: Python interpreter state is not initialized. The process may be terminated.
     [[{{node PyFunc}}]]

那么我做错了什么?如何微调两个 resnet 的所有层并让这两个输入模型进行训练?

4

0 回答 0