一维卷积和二维卷积运算方法及思路

请大家指点一下卷积运算该怎么思考,一维卷积运算有点能明白,二维的不知道该怎么计算,网上也没找到很好的资料,谢谢大家

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7806825
  • 你也可以参考下这篇文章:以一元及二元函数为例,通过多项式的函数图像观察其拟合性能;以及对用多项式作目标函数进行机器学习时的一些理解。
  • 除此之外, 这篇博客: 机器视觉自动数据标注方法中的 (半)自动数据标注的方法基本都是采用类似的思路,即通过少量标注数据进行训练后得到一个预训练模型,然后再次基础上对该网络的输出结果进行人工核验,并进一步地进行训练得到第二轮优化模型,往复循环,增加更多数据提高模型精度。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
  • 您还可以看一下 张飞老师的硬件开发与电路设计速成入门到精通视频教程第一部课程中的 稳压线性电源工作原理分析小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    对于一维卷积,它是将一个长度为n的向量和一个长度为m的向量通过滑动点积的方式得到一个长度为n-m+1的向量,即:

    length_n = n
    length_m = m
    res = []
    for i in range(length_n - length_m + 1):
        temp = 0
        for j in range(length_m):
            temp += vector1[i+j]*vector2[j]
        res.append(temp)
    

    而对于二维卷积,它是将一个大小为nxm的矩阵(或者称为特征图)和一个大小为pxq的矩阵(或者称为卷积核)通过滑动点积的方式得到一个大小为(n-p+1)x(m-q+1)的矩阵(或者称为输出特征图),即:

    import numpy as np
    
    def conv2d(image, kernel, stride=[1,1], padding='VALID'):
        if padding == 'VALID':
            padding_size = [0, 0]
        elif padding == 'SAME':
            padding_height = ((image.shape[1] - 1) * stride[0] + kernel.shape[0] - image.shape[0])
            padding_width = ((image.shape[2] - 1) * stride[1] + kernel.shape[1] - image.shape[1])
            padding_height = int(padding_height/2)
            padding_width = int(padding_width/2)
            padding_size = [padding_height, padding_width]
        else:
            raise ValueError('padding must be either VALID or SAME.')
    
        padded_image = np.pad(image, ((0, 0), (padding_size[0], padding_size[0]), (padding_size[1], padding_size[1]), (0, 0)), mode='constant', constant_values=0)
    
        output_height = int((padded_image.shape[1] - kernel.shape[0]) / stride[0] + 1)
        output_width = int((padded_image.shape[2] - kernel.shape[1]) / stride[1] + 1)
        output = np.zeros((padded_image.shape[0], output_height, output_width, kernel.shape[3]))
    
        kernel = np.flipud(np.fliplr(kernel))
    
        for y in range(output_height):
            for x in range(output_width):
                output[:, y, x, :] = (kernel * padded_image[:, y * stride[0]:y * stride[0] + kernel.shape[0], x * stride[1]:x * stride[1] + kernel.shape[1], :]).sum(axis=(1, 2))
    
        return output
    

    其中,padding参数指定是否需要对边缘进行填充,当为VALID时不进行填充,输出大小为(n-p+1)x(m-q+1);当为SAME时进行填充,填充后输出大小为nxm。stride参数指定卷积时的步长。padding_size表示 padding高度和宽度。

    需要注意的是,卷积核也是一个张量,且有多个通道,一般用于提取图像不同方向或者频率的特征。因此,在二维卷积中,应该遍历卷积核的所有通道,并按通道进行滑动点积。可用以下代码实现:

    output = np.zeros((padded_image.shape[0], output_height, output_width, kernel.shape[3]))
    
    for i in range(kernel.shape[3]):
        for y in range(output_height):
            for x in range(output_width):
                output[:, y, x, i] = (kernel[:, :, :, i] * padded_image[:, y * stride[0]:y * stride[0] + kernel.shape[0], x * stride[1]:x * stride[1] + kernel.shape[1], :]).sum(axis=(1, 2, 3))
    

    这里,输出矩阵output的第四维是卷积核的通道数。针对每一个通道,提取图像不同方向或者频率的特征。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^