矩阵乘法实现卷积运算

利用Matrix Multiplication实现Convolutions

在这里插入图片描述
以feature map : channel=1,stride=1,padding=0为例,解决:1、如何将feature map和 filter kernel进行unfold ;2、如何进行卷积运算的问题。

import numpy as np
from numpy import zeros
#将feature map unfold
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

w = np.array([[1, 2, 3], [4, 5, 6], [-1, -2, -3]], np.float32)
#x = np.random.randn(5,5)
x = np.array([[-0.21556299, -0.11002319, -0.3499612,   1.49290769, -0.50435978],
 [ 0.06348409,  0.66873375,  0.14251138, -1.6414004 , -0.91561852],
 [-2.52451962, -1.97544675, -0.24609529, -1.11489934, -1.44793437],
 [ 1.26260575, -0.62047366,  0.12274525,  0.25200227, -0.83925847],
 [-1.54336488, -0.05100702,  0.36608208,  0.51712927, -0.97133877],
[-1.54336488, -0.05100702, 0.36608208, 0.51712927, -0.97133877]])

n, m = x.shape[0:2]
k = w.shape[0]

x_unfolded = unfold_matrix(x, k)
w_flat = w.flatten()
yy = np.matmul(x_unfolded, w_flat)
yy = yy.reshape((n-k+1, m-k+1))
print(yy)

卷积运算方式发展史

CuDNN v1.0 released in Aug 2014使用矩阵乘法实现卷积运算,因为大量优化矩阵运算的库,使得这种方式已经能高效的实现卷积的运算。但这种方式不是最高效的,更高效的实现方式有Fast Fourier Transform (FFT) and the Winograd transformation等。一般来说,Fast Fourier Transform (FFT)适合于大尺度的filter sizes,而Winograd更适合与小尺度的filter sizes(3×3 or 5×5)。
在这里插入图片描述

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卷积神经网络中,卷积操作是非常重要的一环。在卷积操作中,我们需要对输入图像进行卷积核的滑动窗口运算,得到卷积特征图。我们可以通过矩阵乘法实现卷积操作。 具体地,我们可以将输入图像和卷积核都展开为矩阵,然后通过矩阵乘法来进行卷积操作。假设输入图像为 $I$,大小为 $H \times W \times C$,卷积核为 $K$,大小为 $K_h \times K_w \times C \times K_c$,其中 $H,W,C,K_h,K_w,K_c$ 分别表示输入图像的高度、宽度、通道数和卷积核的高度、宽度、通道数,那么我们可以将 $I$ 展开为一个 $HW \times C$ 的矩阵,将 $K$ 展开为一个 $CK_hK_w \times K_c$ 的矩阵,然后将它们相乘,得到一个大小为 $HW \times K_c$ 的矩阵,最后再将它 reshape 回 $H \times W \times K_c$ 的大小,就得到了卷积特征图。 具体的实现可以利用 NumPy 中的 dot 函数来实现矩阵乘法,具体代码如下: ```python import numpy as np def conv2d(image, kernel): # 获取矩阵的大小 H, W, C = image.shape K_h, K_w, _, K_c = kernel.shape # 展开输入图像和卷积核 image_matrix = np.reshape(image, [H * W, C]) kernel_matrix = np.reshape(kernel, [K_h * K_w * C, K_c]) # 矩阵乘法 feature_matrix = np.dot(image_matrix, kernel_matrix) # 将矩阵 reshape 回特征图的大小 feature = np.reshape(feature_matrix, [H, W, K_c]) return feature ``` 需要注意的是,这种基于矩阵乘法实现卷积的方法一般只适用于卷积核较小的情况,因为当卷积核较大,展开后的矩阵会非常大,会占用大量的内存和计算资源。因此在实际的卷积神经网络中,我们一般会使用更加高效的卷积算法,如基于 im2col 的卷积算法和基于快速 Fourier 变换的卷积算法等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值