J'utilise Python 3.7.7. et Tensorflow 2.1.0.
J'ai un réseau VGG16 pré-formé, et je veux obtenir les premières couches, c'est-à-dire de la couche conv1 à la couche conv5.
Dans l'image suivante:
Vous pouvez voir une architecture codeur-décodeur convolutif. Je veux obtenir la partie encodeur, c'est-à-dire les calques qui apparaissent à gauche de l'image:
Ce n'est qu'un exemple mais si j'obtiens le VGG16 de cette fonction:
model_new = Model(input=model_old.layers[0].input, output=model_old.layers[12].output)
Je forme le réseau, puis je le forme. Comment puis-je obtenir la partie encodeur? En d' autres termes, obtenir le modèle un avec seulement les couches d' origine de conv1
à pool5
.
Je pense que ça pourrait être quelque chose comme ça:
def vgg16_encoder_decoder(input_size = (200,200,1)): ################################# # Encoder ################################# inputs = Input(input_size, name = 'input') conv1 = Conv2D(64, (3, 3), activation = 'relu', padding = 'same', name ='conv1_1')(inputs) conv1 = Conv2D(64, (3, 3), activation = 'relu', padding = 'same', name ='conv1_2')(conv1) pool1 = MaxPooling2D(pool_size = (2,2), strides = (2,2), name = 'pool_1')(conv1) conv2 = Conv2D(128, (3, 3), activation = 'relu', padding = 'same', name ='conv2_1')(pool1) conv2 = Conv2D(128, (3, 3), activation = 'relu', padding = 'same', name ='conv2_2')(conv2) pool2 = MaxPooling2D(pool_size = (2,2), strides = (2,2), name = 'pool_2')(conv2) conv3 = Conv2D(256, (3, 3), activation = 'relu', padding = 'same', name ='conv3_1')(pool2) conv3 = Conv2D(256, (3, 3), activation = 'relu', padding = 'same', name ='conv3_2')(conv3) conv3 = Conv2D(256, (3, 3), activation = 'relu', padding = 'same', name ='conv3_3')(conv3) pool3 = MaxPooling2D(pool_size = (2,2), strides = (2,2), name = 'pool_3')(conv3) conv4 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv4_1')(pool3) conv4 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv4_2')(conv4) conv4 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv4_3')(conv4) pool4 = MaxPooling2D(pool_size = (2,2), strides = (2,2), name = 'pool_4')(conv4) conv5 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv5_1')(pool4) conv5 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv5_2')(conv5) conv5 = Conv2D(512, (3, 3), activation = 'relu', padding = 'same', name ='conv5_3')(conv5) pool5 = MaxPooling2D(pool_size = (2,2), strides = (2,2), name = 'pool_5')(conv5) ################################# # Decoder ################################# #conv1 = Conv2DTranspose(512, (2, 2), strides = 2, name = 'conv1')(pool5) upsp1 = UpSampling2D(size = (2,2), name = 'upsp1')(pool5) conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv6_1')(upsp1) conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv6_2')(conv6) conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv6_3')(conv6) upsp2 = UpSampling2D(size = (2,2), name = 'upsp2')(conv6) conv7 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv7_1')(upsp2) conv7 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv7_2')(conv7) conv7 = Conv2D(512, 3, activation = 'relu', padding = 'same', name = 'conv7_3')(conv7) zero1 = ZeroPadding2D(padding = ((1, 0), (1, 0)), data_format = 'channels_last', name='zero1')(conv7) upsp3 = UpSampling2D(size = (2,2), name = 'upsp3')(zero1) conv8 = Conv2D(256, 3, activation = 'relu', padding = 'same', name = 'conv8_1')(upsp3) conv8 = Conv2D(256, 3, activation = 'relu', padding = 'same', name = 'conv8_2')(conv8) conv8 = Conv2D(256, 3, activation = 'relu', padding = 'same', name = 'conv8_3')(conv8) upsp4 = UpSampling2D(size = (2,2), name = 'upsp4')(conv8) conv9 = Conv2D(128, 3, activation = 'relu', padding = 'same', name = 'conv9_1')(upsp4) conv9 = Conv2D(128, 3, activation = 'relu', padding = 'same', name = 'conv9_2')(conv9) upsp5 = UpSampling2D(size = (2,2), name = 'upsp5')(conv9) conv10 = Conv2D(64, 3, activation = 'relu', padding = 'same', name = 'conv10_1')(upsp5) conv10 = Conv2D(64, 3, activation = 'relu', padding = 'same', name = 'conv10_2')(conv10) conv11 = Conv2D(1, 3, activation = 'relu', padding = 'same', name = 'conv11')(conv10) model = Model(inputs = inputs, outputs = conv11, name = 'vgg-16_encoder_decoder') return model
3 Réponses :
from tensorflow.keras.applications import VGG16 from tensorflow.keras.layers import Input, Flatten from tensorflow.keras import Model input_shape = (W,H,C) def encoder(input_shape): model = VGG16(include_top=False, input_shape=input_shape) F1 = Flatten()(model.get_layer(index=1).output) F2 = Flatten()(model.get_layer(index=2).output) F3 = Flatten()(model.get_layer(index=3).output) F4 = Flatten()(model.get_layer(index=4).output) F5 = Flatten()(model.get_layer(index=5).output) M = Model(model.inputs,[F1,F2,F3,F4,F5]) return M Where W,H the image size and C the numbre of chnnel should equal to 3.
Merci mais votre réponse ne répond pas à ma question. Je dois obtenir l'encodeur pour un réseau pré-formé, pas pour implémenter un encodeur basé sur l'architecture VGG16.
Pour obtenir la rencontre de mon réseau pré-formé, j'ai créé cette fonction:
def get_encoder(old_model: Model) -> Model: # Get encoder encoder_input: Model = Model(inputs=old_model.layers[0].input, outputs=old_model.layers[14].output) # Create Global Average Pooling. encoder_output = GlobalAveragePooling2D()(encoder_input.layers[-1].output) # Create the encoder adding the GAP layer as output. encoder: Model = Model(encoder_input.input, encoder_output, name='encoder') return encoder
L'important est le nombre 14
. Il s'agit de la couche où la rencontre se termine dans le réseau d'origine. En passant, j'ai finalement utilisé U-Net
au lieu de VGG-16
, donc ce numéro ne fonctionne que pour U-NET .
Je suggérerais le code suivant, en omettant les 20 dernières couches de votre code.
model_new = Model(model_old.input, model_old.layers[-20].output) model_new.summary()
Vous devrez peut-être l'ajuster légèrement à -19 ou -21 pour trouver le dernier pool5 si j'ai manqué le comptage des 20 dernières couches pour le décodeur.
Que voulez-vous exactement? Les poids des couches ou leurs sorties?
@GilPinsky J'ai mis à jour ma question.