TensorFlow: Unpooling

Existe-t-il une fonction native TensorFlow qui permet de débloquer les réseaux Déconvolutionnels ?

j'ai écrit ceci en python normal, mais cela devient compliqué quand vous voulez le traduire en TensorFlow car ses objets ne supportent même pas l'assignation d'item pour le moment, et je pense que C'est un grand inconvénient avec TF.

21
demandé sur VM_AI 2016-04-11 15:29:21

3 réponses

Je ne pense pas qu'il y ait encore une couche officielle de désamorçage, ce qui est frustrant parce que vous devez utiliser l'image redimensionnée (interpolation bilinéaire ou plus proche voisin) qui est comme une opération de désamorçage moyenne et c'est vraiment lent. Regardez l'api tf dans la section 'image' et vous le trouverez.

Tensorflow a une chose maxpooling_with_argmax où vous obtenez la sortie maxpooled ainsi que la carte d'activation qui est agréable car vous pourriez l'utiliser dans une couche de déspoolage pour préserver l'information spatiale "perdue", mais il semble qu'il n'y ait pas une telle opération désordonnée qui le fait. Je suppose qu'ils sont la planification pour l'ajouter ... bientôt.

Edit: j'ai trouvé un gars sur google discuter Il ya une semaine qui semble avoir mis en œuvre quelque chose comme cela, mais je n'ai personnellement pas encore essayé. https://github.com/ppwwyyxx/tensorpack/blob/master/tensorpack/models/pool.py#L66

14
répondu Shagas 2016-04-16 06:36:36

il y a quelques implémentations ici WhatWhereAutoencoder.py

à savoir:

1) opération non cool ( source) qui utilise la sortie de tf.nn.max_pool_with_argmax. Bien que s'il vous plaît noter, qu'à partir de tensorflow 1.0 tf.nn.max_pool_with_argmax GPU-seulement

2) opération d'échantillonnage qui imite inverse de Max-pooling en remplissant les positions de la région non refroidie avec des zéros ou des copies de l'élément max. En comparant tensorpack elle permet de copies d'éléments au lieu de zéros et supporte des Pas autres que [2, 2].

Pas de recompiler, arrière-prop-friendly.

Illustration: Upsampling

Unpooling

8
répondu yauheni_selivonchyk 2017-03-02 07:31:13

je cherchais un maxdésamorcer l'opération et essayé de la mettre en œuvre. Je suis venu avec une sorte de hacky mise en œuvre pour le dégradé, pendant que je luttais avec CUDA.

le code est ici, vous aurez besoin de le construire à partir de la source avec le support GPU. Ci-dessous une application de démonstration. Aucune garantie, si!

Il existe aussi un question pour ce opération.

import tensorflow as tf
import numpy as np

def max_pool(inp, k=2):
    return tf.nn.max_pool_with_argmax_and_mask(inp, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding="SAME")

def max_unpool(inp, argmax, argmax_mask, k=2):
    return tf.nn.max_unpool(inp, argmax, argmax_mask, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding="SAME")

def conv2d(inp, name):
    w = weights[name]
    b = biases[name]
    var = tf.nn.conv2d(inp, w, [1, 1, 1, 1], padding='SAME')
    var = tf.nn.bias_add(var, b)
    var = tf.nn.relu(var)
    return var

def conv2d_transpose(inp, name, dropout_prob):
    w = weights[name]
    b = biases[name]

    dims = inp.get_shape().dims[:3]
    dims.append(w.get_shape()[-2]) # adpot channels from weights (weight definition for deconv has switched input and output channel!)
    out_shape = tf.TensorShape(dims)

    var = tf.nn.conv2d_transpose(inp, w, out_shape, strides=[1, 1, 1, 1], padding="SAME")
    var = tf.nn.bias_add(var, b)
    if not dropout_prob is None:
        var = tf.nn.relu(var)
        var = tf.nn.dropout(var, dropout_prob)
    return var


weights = {
    "conv1":    tf.Variable(tf.random_normal([3, 3,  3, 16])),
    "conv2":    tf.Variable(tf.random_normal([3, 3, 16, 32])),
    "conv3":    tf.Variable(tf.random_normal([3, 3, 32, 32])),
    "deconv2":  tf.Variable(tf.random_normal([3, 3, 16, 32])),
    "deconv1":  tf.Variable(tf.random_normal([3, 3,  1, 16])) }

biases = {
    "conv1":    tf.Variable(tf.random_normal([16])),
    "conv2":    tf.Variable(tf.random_normal([32])),
    "conv3":    tf.Variable(tf.random_normal([32])),
    "deconv2":  tf.Variable(tf.random_normal([16])),
    "deconv1":  tf.Variable(tf.random_normal([ 1])) }


## Build Miniature CEDN
x = tf.placeholder(tf.float32, [12, 20, 20, 3])
y = tf.placeholder(tf.float32, [12, 20, 20, 1])
p = tf.placeholder(tf.float32)

conv1                                   = conv2d(x, "conv1")
maxp1, maxp1_argmax, maxp1_argmax_mask  = max_pool(conv1)

conv2                                   = conv2d(maxp1, "conv2")
maxp2, maxp2_argmax, maxp2_argmax_mask  = max_pool(conv2)

conv3                                   = conv2d(maxp2, "conv3")

maxup2                                  = max_unpool(conv3, maxp2_argmax, maxp2_argmax_mask)
deconv2                                 = conv2d_transpose(maxup2, "deconv2", p)

maxup1                                  = max_unpool(deconv2, maxp1_argmax, maxp1_argmax_mask)
deconv1                                 = conv2d_transpose(maxup1, "deconv1", None)


## Optimizing Stuff
loss        = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(deconv1, y))
optimizer   = tf.train.AdamOptimizer(learning_rate=1).minimize(loss)


## Test Data
np.random.seed(123)
batch_x = np.where(np.random.rand(12, 20, 20, 3) > 0.5, 1.0, -1.0)
batch_y = np.where(np.random.rand(12, 20, 20, 1) > 0.5, 1.0,  0.0)
prob    = 0.5


with tf.Session() as session:
    tf.set_random_seed(123)
    session.run(tf.initialize_all_variables())

    print "\n\n"
    for i in range(10):
        session.run(optimizer, feed_dict={x: batch_x, y: batch_y, p: prob})
        print "step", i + 1
        print "loss",  session.run(loss, feed_dict={x: batch_x, y: batch_y, p: 1.0}), "\n\n"

Modifier 29.11.17

Il y a quelque temps, je l'ai réimplémenté d'une manière propre contre TensorFlow 1.0, les opérations forward sont également disponibles en version CPU. Vous pouvez le trouver dans cette branche, je vous recommande de regarder ce dernier s'engage, si vous voulez l'utiliser.

6
répondu jns 2017-11-29 20:42:49