16 votes

Les images de formation CNN de Tensorflow sont toutes de tailles différentes.

J'ai créé un réseau neuronal à convolution profonde pour classer les pixels individuels d'une image. Mes données de formation seront toujours de la même taille (32x32x7), mais mes données de test peuvent être de n'importe quelle taille.

Dépôt Github

Actuellement, mon modèle ne fonctionne que sur des images de même taille. J'ai utilisé le mnist de tensorflow. tutorial largement pour m'aider à construire mon modèle. Dans ce tutoriel, nous n'utilisons que des images 28x28. Comment le modèle mniste suivant pourrait-il être modifié pour accepter des images de toute taille ?

 x = tf.placeholder(tf.float32, shape=[None, 784])
 y_ = tf.placeholder(tf.float32, shape=[None, 10])
 W = tf.Variable(tf.zeros([784,10]))
 b = tf.Variable(tf.zeros([10]))
 x_image = tf.reshape(x, [-1, 28, 28, 1])

Pour rendre les choses un peu plus compliquées, mon modèle comporte des convolutions de transposition où la forme de la sortie doit être spécifiée. Comment puis-je ajuster la ligne de code suivante pour que la convolution de transposition produise une forme de la même taille que l'entrée.

  DeConnv1 = tf.nn.conv3d_transpose(layer1, filter = w, output_shape = [1,32,32,7,1], strides = [1,2,2,2,1], padding = 'SAME')

6voto

gidim Points 1777

Malheureusement, il n'existe aucun moyen de créer des graphes dynamiques dans Tensorflow (Vous pouvez essayer avec pliage mais cela sort du cadre de la question). Cela vous laisse deux options :

  1. Bucketing : Vous créez de multiples tenseurs d'entrée dans quelques tailles sélectionnées, puis vous choisissez le bon seau lors de l'exécution (voir l'exemple). Dans tous les cas, vous aurez probablement besoin de la deuxième option. Seq2seq avec bucketing

  2. Redimensionnez les images d'entrée et de sortie. En supposant que les images conservent toutes le même rapport d'aspect, vous pouvez essayer de redimensionner l'image avant l'inférence. Je ne vois pas pourquoi vous vous souciez de la sortie puisque MNIST est une tâche de classification.

Dans les deux cas, vous pouvez utiliser la même approche :

from PIL import Image

basewidth = 28 # MNIST image width
img = Image.open('your_input_img.jpg')
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)

# Save image or feed directly to tensorflow 
img.save('feed_to_tf.jpg')

1voto

Abhijit Balaji Points 626

Le code du modèle mnist que vous avez mentionné est un exemple utilisant des réseaux FC et non des réseaux de convolution. La forme d'entrée de [None,784] est donnée pour la taille de mnist (28 x 28). L'exemple est un réseau FC qui a une taille d'entrée fixe.

Ce que vous demandez n'est pas possible dans les réseaux FC car le nombre de poids et de biais dépend de la forme de l'entrée. Cela est possible si vous utilisez une architecture de convolution complète. Ma suggestion est donc d'utiliser une architecture de convolution complète afin que les poids et les biais ne dépendent pas de la forme de l'entrée.

1voto

RafazZ Points 911

Ajouter à La réponse de @gidim Si vous êtes un utilisateur de Tensorflow, voici comment vous pouvez redimensionner les images dans Tensorflow et intégrer les résultats directement dans votre inférence. Remarque : Cette méthode met l'image à l'échelle et la déforme, ce qui peut augmenter votre perte.

Tout le mérite revient à Article de Prasad Pai sur l'augmentation des données .

import tensorflow as tf
import numpy as np
from PIL import Image

IMAGE_SIZE = 32
CHANNELS = 1

def tf_resize_images(X_img_file_paths):
    X_data = []
    tf.reset_default_graph()
    X = tf.placeholder(tf.float32, (None, None, CHANNELS))
    tf_img = tf.image.resize_images(X, (IMAGE_SIZE, IMAGE_SIZE), 
                                    tf.image.ResizeMethod.NEAREST_NEIGHBOR)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        # Each image is resized individually as different image may be of different size.
        for index, file_path in enumerate(X_img_file_paths):
            img = Image.open(file_path)
            resized_img = sess.run(tf_img, feed_dict = {X: img})
            X_data.append(resized_img)

    X_data = np.array(X_data, dtype = np.float32) # Convert to numpy
    return X_data

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X