web-dev-qa-db-ja.com

TensorFlow:プール解除

デコンボリューショナルネットワークのプール解除を行うTensorFlowネイティブ関数はありますか?

私はこれを通常のPythonで書いていますが、オブジェクトが現在アイテムの割り当てをサポートしていないため、TensorFlowに変換したい場合は複雑になります。これはTFにとって大きな不便だと思います。

22
VM_AI

公式のプール解除レイヤーはまだないと思いますが、これは平均的なプール解除操作のような画像サイズ変更(双線形補間または最近傍)を使用しなければならず、非常に遅いため、イライラします。セクション 'image'のtf apiを見てください。

Tensorflowにはmaxpooling_with_argmaxがあり、maxpooled出力とアクティベーションマップを取得できます。アクティベーションマップは、「失われた」空間情報を保持するためにプール解除レイヤーで使用できますが、プール解除操作はないようですそれをします。彼らはそれを追加することを計画していると思います...すぐに。

編集:1週間前に、Googleでこのようなものを実装しているように見える人を見つけましたが、個人的にはまだ試していません。 https://github.com/ppwwyyxx/tensorpack/blob/master/tensorpack/models/pool.py#L66

14
Shagas

ここにはいくつかのテンソルフローの実装があります pooling.py

すなわち:

1)tf.nn.max_pool_with_argmaxの出力を利用するプール解除操作( source )注意してください、tensorflow 1.0の時点でtf.nn.max_pool_with_argmaxはGPUのみです

2)プールされていない領域の位置をゼロまたは最大要素のコピーで埋めることにより、最大プールの逆を模倣するアップサンプル操作。 tensorpack と比較すると、ゼロではなく要素のコピーが許可され、[2, 2]以外のストライドがサポートされます。

再コンパイルなし、バックプロップフレンドリー。

イラスト: Upsampling

Unpooling

9
y.selivonchyk

私はmaxアンプール操作を探していて、それを実装しようとしました。 CUDAに苦労していたので、ある種の 勾配のハックな実装 を思いつきました。

コードは here です。GPUサポートを使用してソースからビルドする必要があります。以下はデモアプリケーションです。ただし、保証はありません!

この操作には 未解決の問題 もあります。

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"

29.11.17を編集

しばらく前に、TensorFlow 1.0に対してクリーンな方法で再実装しました。フォワード操作はCPUバージョンとしても利用できます。あなたはそれを見つけることができます このブランチで 、それを使用したい場合、最後のいくつかのコミットを調べることをお勧めします。

6
jns