【问题标题】:Tensorflow, Reshape like a convolutionTensorflow,像卷积一样重塑
【发布时间】:2018-04-03 22:02:28
【问题描述】:

我有一个矩阵 [3,3,256],我的最终输出必须是 [4,2,2,256],我必须使用像“卷积”这样的重塑而不改变值。 (在这种情况下使用过滤器 2x2)。有没有使用 tensorflow 的方法来做到这一点?

【问题讨论】:

    标签: tensorflow convolution


    【解决方案1】:

    如果我正确理解您的问题,您希望将原始值冗余存储在新结构中,如下所示(没有最后一个暗淡 256):

    [ [ 1 2 3 ]          [ [ 1 2 ]    [ [ 2 3 ]    [ [ 4 5 ]     [ [ 5 6 ]
      [ 4 5 6 ]       =>   [ 4 5 ] ],   [ 5 6 ] ],   [ 7 8 ] ],    [ 8 9 ] ]
      [ 7 8 9 ] ]
    

    如果是,您可以像这样使用索引,将x 作为原始张量,然后将它们堆叠起来:

    x2 = []
    for i in xrange( 2 ):
         for j in xrange( 2 ):
             x2.append( x[ i : i + 2, j : j + 2, : ] )
    y = tf.stack( x2, axis = 0 )
    

    根据您的评论,如果您真的想避免使用任何循环,您可以使用tf.extract_image_patches,如下所示(经过测试的代码),但您应该运行一些测试,因为这实际上可能是在效率和性能方面比上面的差很多:

    import tensorflow as tf
    sess = tf.Session()
    x = tf.constant( [ [ [ 1, -1 ], [ 2, -2 ], [ 3, -3 ] ],
                       [ [ 4, -4 ], [ 5, -5 ], [ 6, -6 ] ],
                       [ [ 7, -7 ], [ 8, -8 ], [ 9, -9 ] ] ] )
    xT = tf.transpose( x, perm = [ 2, 0, 1 ] ) # have to put channel dim as batch for tf.extract_image_patches
    xTE = tf.expand_dims( xT, axis = -1 ) # extend dims to have fake channel dim
    xP = tf.extract_image_patches( xTE, ksizes = [ 1, 2, 2, 1 ],
            strides = [ 1, 1, 1, 1 ], rates = [ 1, 1, 1, 1 ], padding = "VALID" )
    y = tf.transpose( xP, perm = [ 3, 1, 2, 0 ] ) # move dims back to original and new dim up front
    
    print( sess.run(y) )
    

    输出(手动添加水平分隔线以提高可读性):

    [[[[ 1 -1] [2 -2]]

    [[ 4 -4] [5 -5]]]


    [[[ 2 -2] [3 -3]]

    [[ 5 -5] [6 -6]]]


    [[[ 4 -4] [5 -5]]

    [[ 7 -7] [8 -8]]]


    [[[ 5 -5] [6 -6]]

    [[ 8 -8] [9 -9]]]]

    【讨论】:

    • 是的,但问题是我不能使用循环(为了提高效率)
    • 嗯,它只在开始时使用一次循环来设置网络。一旦它启动并使用 sess.run( y ) 运行它,它就会被 Tensorflow 优化。
    • 用无循环版本更新了我的答案
    【解决方案2】:

    我和你有类似的问题,我发现在tf.contrib.kfac.utils 中有一个名为extract_convolution_patches 的函数。假设你有一个张量X,形状为(1, 3, 3, 256),其中最初的 1 标志着批量大小,你可以调用

    Y = tf.contrib.kfac.utils.extract_convolution_patches(X, (2, 2, 256, 1), padding='VALID')
    Y.shape    # (1, 2, 2, 2, 2, 256)
    

    前两个 2 将是您的输出过滤器的数量(构成您描述中的 4)。后两个 2 将是过滤器的形状。然后你可以调用

    Y = tf.reshape(Y, [4,2,2,256])
    

    得到你的最终结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2016-05-27
      • 2016-02-26
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      相关资源
      最近更新 更多