2017-07-07 6 views
1

J'essayais de construire un Encodeur Variation Auto avec Tensorflow. J'ai commencé avec le modèle le plus simple. J'ai la méthode suivante:Correction de la couche de déconvolution dans Tensorflow

def conv_layer(x, w_shape, b_shape, padding='SAME'): 
    W = weight_variable(w_shape) 
    tf.summary.histogram(W.name, W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram(b.name, b) 

    # Note that I used a stride of 2 on purpose in order not to use max pool layer. 
    activations = tf.nn.relu(tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding=padding) + b) 
    tf.summary.histogram(activations.name, activations) 
    return activations 

def deconv_layer(x, w_shape, b_shape, padding="SAME"): 
    W = weight_variable(w_shape) 
    tf.summary.histogram(W.name, W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram('bias', b) 

    x_shape = tf.shape(x) 

    out_shape = tf.stack([x_shape[0], x_shape[1], x_shape[2], w_shape[2]]) 
    # Note that I have used a stride of 2 since I used a stride of 2 in conv layer. 
    transposed_activations = tf.nn.conv2d_transpose(x, W, out_shape, [1, 1, 1, 1], padding=padding) + b 
    tf.summary.histogram(transposed_activations.name, transposed_activations) 
    return transposed_activations 

Et le modèle de l'ensemble du réseau est la suivante:

with tf.name_scope('conv1'): 
    conv1 = conv_layer(image, [3, 3, 3, 32], [32]) 
with tf.name_scope('conv2'): 
    conv2 = conv_layer(conv1, [3, 3, 32, 64], [64]) 
with tf.name_scope('conv3'): 
    conv3 = conv_layer(conv2, [3, 3, 64, 128], [128]) 
with tf.name_scope('conv4'): 
    conv4 = conv_layer(conv3, [3, 3, 128, 256], [256]) 

with tf.name_scope('z'): 
    z = conv_layer(conv4, [3, 3, 256, 256], [256]) 

with tf.name_scope('deconv4'): 
    deconv4 = deconv_layer(z, [3, 3, 128, 256], [128]) 
with tf.name_scope('deconv3'): 
    deconv3 = deconv_layer(deconv4, [3, 3, 64, 128], [64]) 
with tf.name_scope('deconv2'): 
    deconv2 = deconv_layer(deconv3, [3, 3, 32, 64], [32]) 
with tf.name_scope('deconv1'): 
    deconv_image = deconv_layer(deconv2, [3, 3, 3, 32], [3]) 

Je reçois mes images d'un FIFOQueue et les introduire dans ce modèle. La taille de mes images est 112, 112, 3. Mon problème est lors du changement des progrès de [1, 1, 1, 1] to [1, 2, 2, 1] dans les deux conv et deconv couches I obtenu l'erreur suivante:

InvalidArgumentError (see above for traceback): Conv2DSlowBackpropInput: Size of out_backprop doesn't match computed: actual = 4, computed = 2 
    [[Node: deconv4/conv2d_transpose = Conv2DBackpropInput[T=DT_FLOAT, data_format="NHWC", padding="SAME", strides=[1, 2, 2, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/gpu:0"](deconv4/stack, deconv4/Variable/read, z/Relu)]] 
    [[Node: deconv1/add/_17 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_85_deconv1/add", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]] 

PS: Je sais que je manque la fonction d'activation à la couche deconv, mais je suppose que cela n'a rien à voir avec l'erreur que j'obtiens. Toute aide est très appréciée !!

+0

J'ai la même erreur. L'avez-vous résolu? – freude

+0

@freude, j'espère que ma réponse a du sens pour vous. S'il vous plaît aimez si vous êtes convaincu. –

+0

@freude, j'ai bien réglé la solution. J'oublie de mentionner le problème avec la forme de sortie. Veuillez revoir la réponse finale et l'accepter si vous étiez convaincu !! merci –

Répondre

0

La raison de cette erreur est la suivante:

Si nous supposons que nous avons stride = 2 à chaque couche de conv, puis, dans mon cas, lorsque l'image d'entrée a une taille de 112, 112, 3, après chaque conv layer la taille du frames ou feature maps après application de la convolution réduit de moitié. Autrement dit, après conv1, la taille (hauteur, largeur) des images devient [56, 56]. Après conv2, la taille devient [28, 28]. Après conv3: [14, 14], après conv4: [7, 7]. Ainsi, en appliquant un conv layer supplémentaire nommé z a réduit les dimensions à [3, 3]. Voici le problème: 7 n'est pas divisible par 2. Donc nous obtenons une dimension différente. aller de [3, 3] à [112, 112] est impossible depuis après l'application deconv layer. En outre:

[3, 3] -> [6, 6] -> [12, 12] -> [24, 24] -> [48, 48] 

Deuxième erreur: la forme de sortie dans le deconv layer devrait être le suivant:

# we should multiply x_shape[1] and x_shape[2] by 2. 
out_shape = tf.stack([x_shape[0], x_shape[1] * 2, x_shape[2] * 2, w_shape[2]]) 

Par conséquent, la deconv layer finale devient comme suit:

def deconv_layer(x, w_shape, b_shape, is_training, padding="SAME", activation='selu'): 
    W = weight_variable(w_shape) 
    tf.summary.histogram("weights", W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram('biases', b) 

    x_shape = tf.shape(x) 
    # output shape: [batch_size, h * 2, w * 2, input_shape from w]. 
    out_shape = tf.stack([x_shape[0], x_shape[1] * 2, x_shape[2] * 2, w_shape[2]]) 
    # Note that I have used a stride of 2 since I used a stride of 2 in conv layer. 
    if activation == 'selu': 
     conv_trans = tf.nn.conv2d_transpose(x, W, out_shape, [1, 2, 2, 1], padding=padding) + b 

     transposed_activations = tf.nn.elu(conv_trans) 

    else: 
     conv_trans = tf.nn.conv2d_transpose(x, W, out_shape, [1, 2, 2, 1], padding=padding) + b 
     transposed_activations = tf.nn.sigmoid(conv_trans) 

    tf.summary.histogram("transpose_activation", transposed_activations) 
    return transposed_activations 

Par conséquent, la taille de la sortie est différente de la taille de l'entrée et c'est pourquoi je reçois l'erreur. Et pour faire back propagation nous avons besoin d'une fonction de coût. Cette fonction de coût dépendra du output et du input. Par conséquent, si elles ont des tailles différentes, cela conduirait à une erreur.

La façon dont cela pourrait être résolu est de laisser le conv layer, z, avoir un stride of 1.

0

La forme de input et deconv_image ne correspond pas lorsque les foulées sont [1, 2, 2, 1] dans le code ci-dessus. La taille decov_image dans ce cas sera [64x64]. Prenez-vous soin de cela ailleurs dans votre code?

+0

Bien quand j'ai modifié le out_shape dans le calque déconv ​​à: 'out_shape = tf.stack ([x_shape [0], x_shape [1] * 2, x_shape [2] * 2, w_shape [2]])' It élaboré. Peut-être que c'était la source de l'erreur. Et cela a du sens. –