1
votes

comment intégrer différentes entrées dans différents modèles?

J'ai 2 tableaux numériques d'images avec la même forme mais un contenu différent:
array1 et array2. Voici deux fonctions différentes:

shape1 = Input(shape=(64,64,3))  
shape2 = Input(shape=(64,64,3))
cmodel = c_model(shape1, "c")
gmodel = g_model(shape2, "g")
m = Model(inputs=[shape1, shape2], outputs=[cmodel, gmodel])
m.compile(...)
m.fit(x=[array1, array2], y=[output1, output2])

Après les lignes suivantes:

def c_model(input_shape, name):

    c_conv1a = Conv2D(64, kernel_size=(7, 7), activation='relu')(input_shape)
    c_conv1a = BatchNormalization(axis=-1)(c_conv1a)
    c_conv1a = MaxPooling2D(pool_size=(2, 2))(c_conv1a)

    flatten = Flatten()(c_conv1a)

    fc = Dense(128, activation='relu')(flatten)
    fc = Dropout(0.3)(fc)
    fc = Dense(256, activation='relu')(fc)
    fc = Dropout(0.3)(fc)
    c_fc = Dense(1, activation='sigmoid', name=name)(fc)

    return c_fc


def g_model(input_shape, name):

    g_conv1a = Conv2D(64, kernel_size=(5, 5), activation='relu')(input_shape)
    g_conv1a = BatchNormalization(axis=-1)(g_conv1a)
    g_conv1a = MaxPooling2D(pool_size=(2, 2))(g_conv1a)

    flatten = Flatten()(g_conv1a)

    fc = Dense(128, activation='relu')(flatten)
    fc = Dropout(0.3)(fc)
    fc = Dense(256, activation='relu')(fc)
    fc = Dropout(0.3)(fc)
    g_fc = Dense(1, activation='sigmoid', name=name)(fc)

    return g_fc

comment puis-je m'assurer que array1 est installé dans cmodel et array2 dans gmodel?


0 commentaires

3 Réponses :


1
votes

Votre graphe de calcul garantit déjà que c'est le cas: vous avez 2 modèles disjoints c et g liés à un modèle externe avec 2 entrées et 2 sorties. La seule façon dont array1 peut affecter output1 est d'utiliser le modèle c et similaire pour array2 ; donc lorsque vous vous entraînez, les gradients par rapport aux sorties ne mettront à jour que le modèle correspondant.

Ce que vous avez équivaut à:

shape1 = Input(shape=(64,64,3))  
shape2 = Input(shape=(64,64,3))
cmodel_out = c_model(shape1, "c")
gmodel_out = g_model(shape2, "g")
cmodel = Model(shape1, cmodel_out)
gmodel = Model(shape2, gmodel_out)
# ... compile models
cmodel.fit(array1, output1)
gmodel.fit(array2, output2)

dans la mesure où le graphe de calcul est concerné.


1 commentaires

Merci, je comprends cela mais je voulais empiler les couches dans un seul modèle () ...



1
votes

Ce sera dans le même ordre que vous avez défini. Vous avez défini [shape1, shape2] , la commande sera celle-ci.

Vous avez passé [array1, array2] , ce sera l'ordre.

Vous avez défini [cmodel, gmodel] ceci est la commande. Vous avez passé [output1, output2] en suivant le même ordre.


2 commentaires

Alors, l'ordre est important? Et si j'ai une autre fonction, disons a_model, quel tableau numpy ira au a_model?


Tu choisis. Vous définissez l'ordre.



0
votes

Si je comprends bien votre question, la façon dont vous le faites garantit déjà ce que vous voulez. Comme déjà indiqué dans les autres réponses, l'ordre des éléments de la liste détermine quel tableau numpy d'entrée sera introduit dans quelle couche d'entrée et quelle couche de sortie sera comparée à quel tableau numpy de sortie.

Si vous ajoutez une troisième entrée dans le constructeur de modèle, par ex. m = Model (inputs = [shape1, shape2, shape3], ...) , vous aurez également besoin d'un troisième tableau numpy d'entrée: m.fit (x = [array1, array2, array3], ...) , sinon vous obtiendrez une erreur.

Si vous ajoutez une troisième sortie dans le constructeur du modèle, par exemple m = Model (output = [cmodel, gmodel, amodel], ...) , vous aurez également besoin d'un troisième tableau numpy de sortie: m.fit (y = [output1, output2, output3], ...) , sinon vous obtiendrez une erreur.

Notez qu'il n'y a aucune raison technique d'avoir le même nombre de couches d'entrée et de sortie. Seules les deux listes passées pour entrées et x et les deux listes passées pour sorties et y doivent avoir la même taille.

Si, pour une raison quelconque, vous ne voulez pas vous fier à cette "correspondance par position d'élément de liste", vous avez l'alternative de passer des dictionnaires à m.fit qui mappent les noms des couches d'entrée et de sortie aux tableaux numpy d'entrée et de sortie:

shape1 = Input(shape=(64,64,3), name="input1")  
shape2 = Input(shape=(64,64,3), name="input2")
cmodel = c_model(shape1, "c")
gmodel = g_model(shape2, "g")
m = Model(inputs=[shape1, shape2], outputs=[cmodel, gmodel])
m.compile(...)
m.fit(x={"input2": array2, "input1": array1}, y={"c": output1, "g": output2})

Quelques remarques supplémentaires: je recommande de nommer vos variables différemment. Vos variables shape1 et shape2 ne sont pas des formes. Ce sont des couches d'entrée (qui ont une certaine forme), donc je préfère les appeler input1 et input2 ou input_layer1 et input_layer2 . De même, vos variables cmodel et gmodel ne sont pas des modèles. Ce sont des couches de sortie d'un modèle. Au lieu de cela, m est votre modèle.

Comme déjà mentionné dans une autre réponse, vos deux "modèles" sont complètement isolés, donc je ne vois pas de raison de les combiner en un seul modèle (à moins, bien sûr, qu'il y ait un lien que vous n'avez pas expliqué plus en détail pour garder la question courte).

Je recommande également de jeter un œil à Documentation Keras concernant les modèles multi-entrées et multi-sorties .


0 commentaires