Как удалить слой FC с тонко обработанной модели keras - PullRequest
2 голосов
/ 08 июля 2019

Итак, я настроил модель Resnet50 со следующей архитектурой:

model = models.Sequential()
model.add(resnet)
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(layers.Dense(2048, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(4096, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(736, activation='softmax')) # Output layer

Итак, теперь у меня есть сохраненная модель (.h5), которую я хочу использовать в качестве ввода в другую модель.Но я не хочу последний слой.Я обычно делал бы это так с базовой моделью resnet50:

def base_model():
    resnet = resnet50.ResNet50(weights="imagenet", include_top=False)
    x = resnet.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(4096, activation='relu')(x)
    x = Dropout(0.6)(x)
    x = Dense(4096, activation='relu')(x)
    x = Dropout(0.6)(x)
    x = Lambda(lambda  x_: K.l2_normalize(x,axis=1))(x)
    return Model(inputs=resnet.input, outputs=x)

, но это не работает для модели, так как выдает ошибку.Я пытаюсь это так прямо сейчас, но, тем не менее, это не работает.

def base_model():
    resnet = load_model("../Models/fine_tuned_model/fine_tuned_resnet50.h5")
    x = resnet.layers.pop()
    #resnet = resnet50.ResNet50(weights="imagenet", include_top=False)
    #x = resnet.output
    #x = GlobalAveragePooling2D()(x)
    x = Dense(4096, activation='relu')(x)
    x = Dropout(0.6)(x)
    x = Dense(4096, activation='relu')(x)
    x = Dropout(0.6)(x)
    x = Lambda(lambda  x_: K.l2_normalize(x,axis=1))(x)
    return Model(inputs=resnet.input, outputs=x)
enhanced_resent = base_model()

Это ошибка, которую она мне дает.

Layer dense_3 was called with an input that isn't a symbolic tensor. Received type: <class 'keras.layers.core.Dense'>. Full input: [<keras.layers.core.Dense object at 0x000001C61E68E2E8>]. All inputs to the layer should be tensors.

Буду признателен за любые указания по этому вопросу, и я не знаю, смогу ли я это сделать или нет.Большое спасибо

1 Ответ

0 голосов
/ 08 июля 2019

Я наконец-то понял это после того, как ушел в течение часа. Вот как ты это сделаешь.

def base_model():
    resnet = load_model("../Models/fine_tuned_model/42-0.85.h5")
    x = resnet.layers[-2].output
    x = Dense(4096, activation='relu', name="FC1")(x)
    x = Dropout(0.6, name="FCDrop1")(x)
    x = Dense(4096, activation='relu', name="FC2")(x)
    x = Dropout(0.6, name="FCDrop2")(x)
    x = Lambda(lambda  x_: K.l2_normalize(x,axis=1))(x)
    return Model(inputs=resnet.input, outputs=x)
enhanced_resent = base_model()

И это прекрасно работает. Я надеюсь, что это поможет кому-то еще, так как я никогда не видел, чтобы это было сделано ни в одном учебном пособии.

x = resnet.layers[-2].output

Это даст нужный вам слой, но вам нужно знать, по какому индексу находится нужный вам слой. -2 - это 2-й до последнего слоя FC, который я хотел, так как я хотел извлечения объектов, а не окончательную классификацию. Это можно найти, делая

model.summary()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...