2017-10-11 4 views
1

J'ai modèle A (autoencoder) qui prend en entrée un lot d'images A_IN (images originales), et délivre un lot d'images A_OUT (images reconstruites). Ensuite, j'ai le modèle B (classificateur binaire) qui prend en entrée un lot d'images B_in, qui est un mélange de A_in et A_out.Comment connecter deux modèles

Je veux faire la distinction entre B et A_IN A_OUT, pour voir si A est en train de faire un bon travail reconstruction d'images. B_out est une probabilité qu'une image donnée soit A_in.

trains B en parallèle avec une de classer les deux types d'images. B_loss = (B_out - étiquette). Les étiquettes sont 0 ou 1 (original ou reconstruit). Lorsque nous optimisons B_loss, nous ne mettons à jour que les paramètres B. Je veux former le modèle A afin qu'il optimise une fonction de perte combinée: Combined_Loss = erreur de reconstruction (A_out - A_in) - erreur de classification (B_out - label), de sorte qu'il tente de reconstruire les images et de tromper B au niveau de la en même temps. Ici, je veux seulement mettre à jour les paramètres A (nous ne voulons pas aider B ici).

Maintenant, ma question porte sur la construction de ce mélange de A_IN et A_OUT, et l'alimentation à B, de sorte que les graphiques A et B sont connectés.

En ce moment, il est comme ça:

A_out = autoencoder(A_in: orig_images) 
B_out = classifier(B_in: numpy(mix(A_in, A_out)) 

Comment définir comme ceci:

A_out = autoencoder(A_in: orig_images) 
B_out = classifier(mix(A_out, A_in)) 

Alors que lorsque je forme A et B en même temps:

sess.run([autoencoder_train_op, classifier_train_op], feed_dict= 
      {A_in: orig_images, B_in: classifier_images, labels: classifier_labels}) 

Je n'aurais pas besoin de B_in placeholder (les graphiques seraient connectés)?

Voici mon code Numpy qui construit classifier_images (mélange (A_IN, A_OUT)):

reconstr_images = sess.run(A_out, feed_dict={A_in: orig_images}) 

half_and_half_images = np.concatenate((reconstr_images[:batch_size/2], orig_images[batch_size/2:])) 

half_and_half_labels = np.zeros(labels.shape) 
half_and_half_labels[batch_size/2:] = 1 

random_indices = np.random.permutation(batch_size) 

classifier_images = half_and_half_images[random_indices] 
classifier_labels = half_and_half_labels[random_indices] 

Comment puis-je convertir en noeud tensorflow?

+0

Y a-t-il un problème spécifique auquel vous êtes confronté en convertissant ce code en tf? Il semble que ce soit du code assez simple qui devrait être faisable en utilisant 'tf.concat',' tf.zeros', 'tf.random_shuffle', etc. Aussi, je ne suis pas sûr de savoir pourquoi vous avez besoin de mélanger du tout. Vraisemblablement, les différentes images alimentées en même temps sont juste pour le traitement par lots et sont traitées indépendamment. Si c'est le cas, vous ne devriez pas avoir besoin de mélanger, à moins que votre taille de lot soit grande et que vous souhaitiez la mélanger pour de meilleures trajectoires d'optimisation. – iga

+0

Bon point sur le brassage - ce n'est pas nécessaire.Cependant cela ne change pas la question principale: comment convertir classifier (B_in: numpy (mix (A_in, A_out)) en classifier (mix (A_out, A_in)) pour que les deux graphes soient connectés? – MichaelSB

+0

je vois. Je vais essayer de répondre avec une réponse – iga

Répondre

0

Vous pouvez connecter vos modèles directement. En d'autres termes, vous n'utilisez pas d'espace réservé pour les entrées de B, mais utilisez votre mélange de A_in et A_out. Si vous voulez juste exécuter B, vous pouvez toujours alimenter vos entrées dans les tenseurs qui viennent de A. Nourrir seulement les espaces réservés est commun, mais TensorFlow prend en charge l'alimentation d'une valeur dans n'importe quel tenseur. Si cela vous facilite la réflexion, vous pouvez passer les sorties A à tf.identity pour avoir quelque chose comme un espace réservé.

Une autre approche est ce qui se fait habituellement dans GAN (où la sortie du générateur est alimenté en discriminateur). Vous pouvez créer deux «tours» d'opérations qui partagent les variables. Une tour sera juste B et vous pouvez nourrir vos entrées dans les espaces réservés de B pour exécuter juste B. Une autre tour peut être B au-dessus de A, que vous pouvez utiliser pour courir/former A et B ensemble. Les Bs dans ces deux tours auront la même structure et partageront des variables, mais auront des ops séparés. Cette approche est probablement la plus propre et la plus flexible.

+0

"mais utilisez votre mélange de A_in et A_out" C'est exactement ce que je voudrais savoir: comment faire ça? Je me demande si je peux le faire comme ceci: 'A_OUT = autoencoder (A_IN: orig_images) mixte = tf.concat (A_OUT, A_IN) B_out = classificateur (mixte)' – MichaelSB

+0

je pourrais manquer quelque chose, mais pourquoi pensez-vous qu'il peut être un problème ? Tant que c'est logiquement correct et les formes correspondent .... Quels problèmes attendez-vous? – iga

+0

Je ne sais pas quels arguments 'classifier' attend, il est donc difficile de dire quoi que ce soit. Il attend des valeurs concrètes qui sont utilisées dans 'feed_dict', il ne va pas" connecter "les modèles. S'il attend des tenseurs et les utilise comme entrées pour ses ops, il va "connecter" les modèles. – iga