Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neural network 作为矩阵乘法的二维卷积_Neural Network_Deep Learning_Conv Neural Network_Matrix Multiplication_Convolution - Fatal编程技术网

Neural network 作为矩阵乘法的二维卷积

Neural network 作为矩阵乘法的二维卷积,neural-network,deep-learning,conv-neural-network,matrix-multiplication,convolution,Neural Network,Deep Learning,Conv Neural Network,Matrix Multiplication,Convolution,我知道,在1D的情况下,两个向量,a和b之间的卷积可以计算为conv(a,b),但也可以计算为T_a和b之间的乘积,其中T_a是a的对应Toeplitz矩阵 有没有可能把这个想法扩展到2D 给定a=[5 1 3;1 1 2;2 1 3]和b=[4 3;1 2],是否可以转换Toeplitz矩阵中的a,并计算T a和b之间的矩阵积,如在一维情况下一样?是的,这是可能的,并且还应该使用双块循环矩阵(这是矩阵的特例).我会给你一个小尺寸的内核和输入的例子,但是可以为任何内核构造Toeplitz矩阵。因

我知道,在1D的情况下,两个向量,
a
b
之间的卷积可以计算为
conv(a,b)
,但也可以计算为
T_a
b
之间的乘积,其中
T_a
a
的对应Toeplitz矩阵

有没有可能把这个想法扩展到2D


给定
a=[5 1 3;1 1 2;2 1 3]
b=[4 3;1 2]
,是否可以转换Toeplitz矩阵中的
a
,并计算
T a
b
之间的矩阵积,如在一维情况下一样?

是的,这是可能的,并且还应该使用双块循环矩阵(这是矩阵的特例).我会给你一个小尺寸的内核和输入的例子,但是可以为任何内核构造Toeplitz矩阵。因此,你有一个2d输入
x
和2d内核
k
,你想计算卷积
x*k
。我们还假设
k
已经翻转了。我们还假设de>x的大小为
n×n
k
的大小为
m×m

因此,将
k
展开成一个大小为
(n-m+1)^2×n^2
的稀疏矩阵,并将
x
展开成一个长向量
n^2×1
。计算该稀疏矩阵与一个向量的乘积,并转换生成的向量(该向量的大小为
(n-m+1)^2×1
)变成一个
n-m+1
方阵

我敢肯定,仅仅从阅读中很难理解这一点。因此,这里有一个2×2内核和3×3输入的示例

这是一个带有向量的构造矩阵:

这等于


这与在
x
上滑动
k
窗口得到的结果相同,如果将k分解为m^2向量并展开x,则得到:

  • a
    m**2
    vector
    k
  • a
    ((n-m)**2,m**2)
    展开X的矩阵
其中
展开的\u X
可以通过以下Python代码获得:

from numpy import zeros


def unroll_matrix(X, m):
  flat_X = X.flatten()
  n = X.shape[0]
  unrolled_X = zeros(((n - m) ** 2, m**2))
  skipped = 0
  for i in range(n ** 2):
      if (i % n) < n - m and ((i / n) % n) < n - m:
          for j in range(m):
              for l in range(m):
                  unrolled_X[i - skipped, j * m + l] = flat_X[i + j * n + l]
      else:
          skipped += 1
  return unrolled_X

上面显示的代码没有生成正确维度的展开矩阵。维度应该是(n-k+1)*(m-k+1),(k)(k)。k:筛选维度,输入矩阵中的n:num行,m:num列

def unfold_matrix(X, k):
    n, m = X.shape[0:2]
    xx = zeros(((n - k + 1) * (m - k + 1), k**2))
    row_num = 0
    def make_row(x):
        return x.flatten()

    for i in range(n- k+ 1):
        for j in range(m - k + 1):
            #collect block of m*m elements and convert to row
            xx[row_num,:] = make_row(X[i:i+k, j:j+k])
            row_num = row_num + 1

    return xx
有关更多详细信息,请参阅我的博客帖子:

1-定义输入和过滤器 设I为输入信号,F为滤波器或内核

2-计算最终输出大小 如果I为m1 x n1,F为m2 x n2,则输出的大小为:

3-将滤波器矩阵归零 零填充过滤器,使其与输出大小相同

4-为零填充过滤器的每一行创建Toeplitz矩阵

5-创建双阻塞Toeplitz矩阵 现在所有这些小的Toeplitz矩阵应该排列在一个大的双阻塞Toeplitz矩阵中。

6-将输入矩阵转换为列向量

7-将双块toeplitz矩阵与矢量化输入信号相乘 此乘法给出卷积结果

8-最后一步:将结果重塑为矩阵形式

有关更多详细信息和python代码,请查看我的github存储库:


最后必须进行某种形式的整形,对吗?最后一个向量是4 x 1,但卷积的结果是2 x2@jvans是的,最后你应该重塑你的向量。它写在这里:转换得到的向量(大小为(n-m+1)^2 X 1)在n-m+1平方矩阵中,你的例子中这不是Toeplitz矩阵。所以你的答案只是部分正确,是吗?你所说的
的意思是什么?让我们假设k已经翻转了
?是因为我们想要执行相关而不是卷积吗?在numpy运算方面,翻转的
是什么上面是一个相关性,这就是为什么他首先垂直(倒置)翻转过滤器,这样它就相当于一个卷积。numpy是
flip(m,0)
,它相当于
flipud(m)
。我认为有一个错误。结果的第一个元素应该是10*0+20*0+30*0+40*1=40。位置2,2的元素应该是1*10+2*20+4*30+5*40=370。对于等于[40 30;20 10]的矩阵F,我认为您的结果是正确的这正是翻转行和列的过程。因此,执行卷积(数学卷积,而非互相关)的过程中存在错误,因此,如果您是手动操作,则需要垂直和水平翻转过滤器。您可以在我的GitHub repo上找到更多信息。这是2D卷积作为矩阵运算的一个很好的解释。是否也有方法表示“mode='same'”(即保持输出形状与图像相同)?@ajl123我想应该是。如果我有时间,我会处理它。如果你得到答案,请随时深入研究代码和数学,并在Github上向我发送一个pull请求。结果矩阵的维数不应该减少吗?请参阅。
def unfold_matrix(X, k):
    n, m = X.shape[0:2]
    xx = zeros(((n - k + 1) * (m - k + 1), k**2))
    row_num = 0
    def make_row(x):
        return x.flatten()

    for i in range(n- k+ 1):
        for j in range(m - k + 1):
            #collect block of m*m elements and convert to row
            xx[row_num,:] = make_row(X[i:i+k, j:j+k])
            row_num = row_num + 1

    return xx