【问题标题】:What is the best way to convolve two matrices in tensorflow?在张量流中卷积两个矩阵的最佳方法是什么?
【发布时间】:2017-12-27 11:29:40
【问题描述】:

假设

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

与 kernel_size=2*2 和 stride=1 卷积后,输出应该是

[[18,18],[28,37]]

我们需要在每个 2*2 部分之间应用卷积操作 A 到 B 的每 2*2 部分。 如何使用 tensorflow 有效地执行此操作? tensorflow有什么方法可以直接做到这一点吗?

【问题讨论】:

    标签: python tensorflow machine-learning deep-learning convolution


    【解决方案1】:

    这是使用tf.nn.conv2D 的一种直接方法:

    In [1055]: A = np.array([[1,2,3],[4,5,6],[7,8,9]])
          ...: B = np.array([[1,1,1],[1,1,1],[1,1,1]])
          ...: 
    
    # define input tensor
    In [1056]: tfA = tf.constant(A, dtype=tf.float32)
    
    # reshape it to 4D tensor (as needed by tf.nn.conv2d)
    In [1057]: tfA = tfA[tf.newaxis, :, :, tf.newaxis]
    
    # define kernel tensor
    In [1058]: tfK = tf.constant(B, dtype=tf.float32)
    
    # again reshape it to 4D tensor (also, we use 2x2 convolution)
    In [1059]: tfK = tfK[:-1, :-1, tf.newaxis, tf.newaxis]
    
    # convolving the input tensor with kernel
    In [1060]: convolved = tf.nn.conv2d(tfA, tfK, strides=[1, 1, 1, 1], padding="VALID")
    
    In [1061]: convolved.eval()
    Out[1061]: 
    array([[[[ 12.],
             [ 16.]],
    
            [[ 24.],
             [ 28.]]]], dtype=float32)
    

    我使用 交互式会话 来评估这些张量,但即使您定义了计算图,然后稍后使用显式会话运行它,它也应该可以正常工作。

    编辑

    另外,澄清一下,这种方法适用于任何(2x2) 内核张量B。考虑以下示例,其中内核张量中的条目加倍。不出所料,最终结果也将比上例中获得的结果翻倍。

    另一个例子:

    In [110]: A = np.array([[1,2,3],[4,5,6],[7,8,9]])
    In [111]: B = np.array([[2,2,2],[2,2,2],[2,2,2]])
    
    In [112]: tfA = tf.constant(A, dtype=tf.float32)
    In [113]: tfA = tfA[tf.newaxis, :, :, tf.newaxis]
    
    In [114]: tfK = tf.constant(B, dtype=tf.float32)
    In [115]: tfK = tfK[:-1, :-1, tf.newaxis, tf.newaxis]
    
    In [116]: convolved = tf.nn.conv2d(tfA, tfK, strides=[1, 1, 1, 1], padding="VALID")
    
    In [117]: convolved.eval()
    Out[117]: 
    array([[[[ 24.],
             [ 32.]],
    
            [[ 48.],
             [ 56.]]]], dtype=float32)
    

    【讨论】:

    • B 可以是任何东西,不必全都是。这对任何 B 都有效吗?
    • 是的,它足够通用,可以处理任何内核张量“B”。
    • @phkr 添加了另一个示例以进行说明。另外,我鼓励您使用不同的内核和输入张量来检查它:)
    • 当 B=[[1,2,1],[2,1,2],[1,1,3]] 时,当 B 的元素彼此不同时,它不起作用。
    【解决方案2】:

    也许这对你有帮助。

    import numpy as np
    from scipy.signal import convolve2d
    
    def conv2(x, y, mode='same'):
        return np.rot90(convolve2d(np.rot90(x, 2), np.rot90(y, 2), mode=mode), 2)
    
    
    A = [[1,2,3],[4,5,6],[7,8,9]]
    B = [[1,1,1],[1,1,1],[1,1,1]]
    
    print(conv2(A,B))
    

    输出将是

    [[12 21 16]
     [27 45 33]
     [24 39 28]]
    

    【讨论】:

    • 我认为 OP 希望在 tensorflow 中做到这一点。此外,您的输出似乎没有什么问题。
    • 是的,我没有应用 2X2 的内核,所以输出不如预期。
    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 2018-03-14
    • 2013-07-31
    • 2019-09-22
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2022-07-01
    相关资源
    最近更新 更多