CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Tensorflow : graph et session

Proutozorent
Proutozorent
Niveau 7
20 mars 2021 à 21:56:52

Hello !
Je suis en train de créer un modèle de CNN basé sur VGG19 mais en modifiant certaines couches, remplacer du maxpooling par du avgpooling par exemple et virer la partie classifieur pour ne garder que la partie convolutive afin d'avoir des patterns visuels et faire du transfert learning. Le problème auquel je suis confronté est que la personne qui m'a passé un exemple de code de la première version de tensorflow, créer son modèle à l'aide d'un graphe comme ça :

def load_vgg_model(VGG19_MODEL, WIDTH = 1280, HEIGHT=720, CHANNELS=3):
        
    def _weights(nLayer):
        #Ici on récupère les poids du modèle original

        W = VGG19_MODEL.layers[nLayer].get_weights()[0]
        b = VGG19_MODEL.layers[nLayer].get_weights()[1]
        return W, b

    def _relu(conv2d_layer):
        #simple fonction relu
        return tf.nn.relu(conv2d_layer)

    def _conv2d(prev_layer, layer):
        #Ici, on créer une couche conv2d basée sur les poids et biais du modèle vgg19 original entraîné

        W, b = _weights(layer)
        W = tf.constant(W)
        b = tf.constant(np.reshape(b, (b.size)))
        return tf.nn.conv2d(prev_layer, filters=W, strides=[1, 1, 1, 1], padding='SAME') + b

    def _conv2d_relu(prev_layer, layer):
        #Ici, on applique relu

        return _relu(_conv2d(prev_layer, layer))

    def _avgpool(prev_layer):
        #Couche avg_pool plutôt que maxpool du modèle original

        return tf.nn.avg_pool(prev_layer, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    
    graph = {}
    graph['input']   = tf.Variable(np.zeros((1, HEIGHT, WIDTH, CHANNELS)), dtype = 'float32')
    graph['conv1_1']  = _conv2d_relu(graph['input'], 1)
    graph['conv1_2']  = _conv2d_relu(graph['conv1_1'], 2)
    graph['avgpool1'] = _avgpool(graph['conv1_2'])
    graph['conv2_1']  = _conv2d_relu(graph['avgpool1'], 4)
    graph['conv2_2']  = _conv2d_relu(graph['conv2_1'], 5)
    graph['avgpool2'] = _avgpool(graph['conv2_2'])
    graph['conv3_1']  = _conv2d_relu(graph['avgpool2'], 7)
    graph['conv3_2']  = _conv2d_relu(graph['conv3_1'], 8)
    graph['conv3_3']  = _conv2d_relu(graph['conv3_2'], 9)
    graph['conv3_4']  = _conv2d_relu(graph['conv3_3'], 10)
    graph['avgpool3'] = _avgpool(graph['conv3_4'])
    graph['conv4_1']  = _conv2d_relu(graph['avgpool3'], 12)
    graph['conv4_2']  = _conv2d_relu(graph['conv4_1'], 13)
    graph['conv4_3']  = _conv2d_relu(graph['conv4_2'], 14)
    graph['conv4_4']  = _conv2d_relu(graph['conv4_3'], 15)
    graph['avgpool4'] = _avgpool(graph['conv4_4'])
    graph['conv5_1']  = _conv2d_relu(graph['avgpool4'], 17)
    graph['conv5_2']  = _conv2d_relu(graph['conv5_1'], 18)
    graph['conv5_3']  = _conv2d_relu(graph['conv5_2'], 19)
    graph['conv5_4']  = _conv2d_relu(graph['conv5_3'], 20)
    graph['avgpool5'] = _avgpool(graph['conv5_4'])
    
    return graph

En gros pour vous faire gagner du temps à la lecture, le but est de créer un graph enchaînant les couches avec les poids et biais du modèle vgg19 original entraîné afin d'accéder plus tard, lors d'un pass forward les activations de différentes couches afin de les utiliser. Le problème est que lorsque je run ce graph dans une Session, j'ai une erreur :

tf.compat.v1.enable_eager_execution() #solution proposée sur stack mais qui ne change rien
[...]
tf.compat.v1.reset_default_graph()
with tf.compat.v1.Session() as sess :
  loaded_model['input'].assign(c_image)
  sess.run(loaded_model)
  out = loaded_model['conv4_2']

  C = sess.run()

RuntimeError: Attempting to capture an EagerTensor without building a function.

J'ai déjà essayé les solutions proposées par les premiers résultats sur stack, autoriser eager exec, désactiver le comportement de la v2 de tensorflow, mais je pense que le problème vient de comment je créer le graph car en vérifiant le type de ce que la fonction load_vgg_model me renvoie, il me renvoie un dictionnaire.

Ce que je cherche à faire exactement :

créer le modèle comme celui de la fonction basé sur le modèle entraîné, où je passe un input de mon choix et me permet de récupérer les activations de la couche de mon choix, dans le code juste en haut, je veux récupérer les activations de la couche "conv4_2".

Proutozorent
Proutozorent
Niveau 7
21 mars 2021 à 12:08:42

Re, après moultes recherches, j'ai trouvé comment résoudre le problème sans trouver une explication à ce qui allait pas. Donc pour rappel, le but était de modifier la structure de VGG19, virer la partie classifieur tout en gardant les poids initiaux du réseau entraîné sur la base imagenet. Puis d'avoir accès aux activations des différentes couches.

Voilà comment j'ai fait du coup pour implémenter :

def VGG19_bis(M, WIDTH = 1280, HEIGHT=720, CHANNELS=3):
  input = keras.layers.Input(shape=(HEIGHT,WIDTH,CHANNELS),name="input_1")

  x = keras.layers.Conv2D(64,(3,3),strides=(1,1),activation='relu',name="conv1_1",weights=[M.layers[1].get_weights()[0],M.layers[1].get_weights()[1]])(input)

  x = keras.layers.Conv2D(64,(3,3),strides=(1,1),activation='relu',name="conv1_2",weights=[M.layers[2].get_weights()[0],M.layers[2].get_weights()[1]])(x)

  x = keras.layers.AveragePooling2D(pool_size=(2,2),strides=(2,2),name="avgpool1")(x)

  x = keras.layers.Conv2D(128,(3,3),strides=(1,1),activation='relu',name="conv2_1",weights=[M.layers[4].get_weights()[0],M.layers[4].get_weights()[1]])(x)

  x = keras.layers.Conv2D(128,(3,3),strides=(1,1),activation='relu',name="conv2_2",weights=[M.layers[5].get_weights()[0],M.layers[5].get_weights()[1]])(x)

  x = keras.layers.AveragePooling2D(pool_size=(2,2),strides=(2,2),name="avgpool2")(x)

  x = keras.layers.Conv2D(256,(3,3),strides=(1,1),activation='relu',name="conv3_1",weights=[M.layers[7].get_weights()[0],M.layers[7].get_weights()[1]])(x)

  x = keras.layers.Conv2D(256,(3,3),strides=(1,1),activation='relu',name="conv3_2",weights=[M.layers[8].get_weights()[0],M.layers[8].get_weights()[1]])(x)

  x = keras.layers.Conv2D(256,(3,3),strides=(1,1),activation='relu',name="conv3_3",weights=[M.layers[9].get_weights()[0],M.layers[9].get_weights()[1]])(x)

  x = keras.layers.Conv2D(256,(3,3),strides=(1,1),activation='relu',name="conv3_4",weights=[M.layers[10].get_weights()[0],M.layers[10].get_weights()[1]])(x)

  x = keras.layers.AveragePooling2D(pool_size=(2,2),strides=(2,2),name="avgpool3")(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv4_1",weights=[M.layers[12].get_weights()[0],M.layers[12].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv4_2",weights=[M.layers[13].get_weights()[0],M.layers[13].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv4_3",weights=[M.layers[14].get_weights()[0],M.layers[14].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv4_4",weights=[M.layers[15].get_weights()[0],M.layers[15].get_weights()[1]])(x)

  x = keras.layers.AveragePooling2D(pool_size=(2,2),strides=(2,2),name="avgpool4")(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv5_1",weights=[M.layers[17].get_weights()[0],M.layers[17].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv5_2",weights=[M.layers[18].get_weights()[0],M.layers[18].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv5_3",weights=[M.layers[19].get_weights()[0],M.layers[19].get_weights()[1]])(x)

  x = keras.layers.Conv2D(512,(3,3),strides=(1,1),activation='relu',name="conv5_4",weights=[M.layers[20].get_weights()[0],M.layers[20].get_weights()[1]])(x)

  M = keras.Model(inputs=input,outputs=x)
  M.trainable = False

  return M

En gros c'est littéralement VGG19 en remplaçant maxpool par avgpool et en ajoutant les poids + biais via weights qui prend une liste de deux élements : [poids, biais]

Pour avoir accès à l'output de n'importe quelle couche du réseau, en gros ce qu'essayais de faire via la session et les graphs :

loaded_model = VGG19_bis(tf.keras.applications.vgg19.VGG19())
extractor = keras.Model(inputs=loaded_model.input,outputs=loaded_model.get_layer("conv4_2").output)

récupérer les features :

features = extractor(data)
Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Création de sites web
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment