深入理解卷积

从数学角度来看卷积是这样的
在这里插入图片描述

卷积是通过两个函数f和g生成第三个函数的一种数学运算,卷积结果可以看作是函数f的修改(过滤)版本。在这个定义中,函数g被称为过滤器filter、卷积函数或卷积核。

第一次看见是在泛函分析,卷积这个东西根本不知道是干什么的有什么用。后来解除了数字图像才明白。

用自然语言举一个物理学中用能量的例子解释:一个物体时刻会受到一个周期性的固定模式的的能量的冲击。并且,物体在受到某个时刻的能量时,会按照一个函数关于时间的函数去变化来自于这个时刻的能量。

更直白的说就是:系统某一时刻的输出是由多个输入共同作用(叠加)的结果。

在这里插入图片描述

最左边的图是输入图像没有经过任何处理的,中间的是卷积核,在卷积核的作用下输出最右边的图像,这就是共同作用的结果。

这图不错:
在这里插入图片描述

那么卷积在图像上能做什么呢?
检测边缘

卷积在图像上具体实现:卷积核从上到下从左到右地滑动,步长自己设定,每一个滑动窗口卷积与对应图像都做乘积求和。

具体代码:

import numpy as np
input = np.array([[1,1,1,0,0],
                  [0,1,1,1,0],
                  [0,0,1,1,1],
                  [0,0,1,1,0]
                 ])
kernel = np.array([[1,0,1],
                   [0,1,0],
                   [1,0,1]
                  ])

print('input.shape')
print(input.shape)

print('输入矩阵的行数:')
x=input.shape[0]
print(input.shape[0])

print('输入矩阵的列数:')
y=input.shape[1]
print(input.shape[1])

print('kernel.shape')
print(kernel.shape)

#坑点:不要照着抄output_size = (len(input)-len(kernel)+1)其中的len(input)不能应用在x,因为x是int型变量

output_size_x=(x-len(kernel)+1)
output_size_y=(y-len(kernel)+1)

def my_conv(input,kernel):
    #output_size = (len(input)-len(kernel)+1)
    res = np.zeros([output_size_x,output_size_y],np.float32)
    for my_conv_x in range(len(res)):
        for my_conv_y in range(len(res)):
            res[my_conv_x][my_conv_y] = compute_conv(input,kernel,my_conv_x,my_conv_y)
    return res

def compute_conv(input,kernel,my_conv_x,my_conv_y):
    res = 0
    for compute_conv_x in range(3):
        for compute_conv_y in range(3):
            #print(input[i+kk][j+k])
            res +=input[my_conv_x+compute_conv_x][my_conv_y+compute_conv_y]*kernel[compute_conv_x][compute_conv_y]  #这句是关键代码,实现了两个矩阵的点乘操作
    return res
print('卷积结果')
print(my_conv(input,kernel)) 

注意:输入地图像不一定是行数等于列数地矩阵,计算卷积用两个for循环就行了very easy
结果如下图,这是用二维数组模拟的卷积,具体图像要对图像做一点处理:
在这里插入图片描述


图像处理的卷积,更改卷积核可以实现不同的边缘检测:

import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np

def matrix_conv(arr,kernel):
    n = len(kernel)
    ans = 0
    for i in range(n):
        for j in range(n):
            ans += arr[i,j]*float(kernel[i,j])
    return ans


def conv_2(image,kernel):
    #kernel的长度,3
    n = len(kernel)
    #2*(n-1)=4
    image_1 = np.zeros((image.shape[0]+2*(n-1),image.shape[1]+2*(n-1)))#516
    image_1[(n - 1):(image.shape[0] + n - 1), (n - 1):(image.shape[1] + n - 1)] = image
    image_2 = np.zeros((image_1.shape[0]-n+1,image_1.shape[1]-n+1))#514
    for i in range(image_1.shape[0]-n+1):
        for j in range(image_1.shape[1]-n+1):
            temp = image_1[i:i+n,j:j+n]
            image_2[i,j] = matrix_conv(temp,kernel)
    new_image = image_2[(n-1):(n+image.shape[0]-1),(n-1):(n+image.shape[1]-1)]
    return new_image
img = cv.imread('./EXP1B.bmp',0)
kernel = np.array([[1,0,-1], [1,-1,0], [2,-1,-1]])  #定义的一个卷积核
img_conv = conv_2(img,kernel)
plt.subplot(1,2,1)
plt.imshow(img,cmap='gray')
plt.subplot(1,2,2)
plt.imshow(img_conv,cmap='gray')
plt.show()

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手撕经典卷积神经网络是指使用numpy纯手写的卷积神经网络代码,该代码可以帮助理解卷积神经网络的原理。它不使用任何神经网络框架,适合那些有意愿深入理解卷积神经网络底层的人群。这个手撕的代码相对简单,但是通过研究它,可以充分理解卷积神经网络的工作原理。 卷积神经网络(CNN)是一种常用于图像处理和识别的深度学习模型。它通过卷积层、池化层和全连接层等组成,实现了对图像特征的提取和分类。在卷积神经网络中,卷积层通过滤波器(卷积核)对输入图像进行卷积操作,以提取图像的局部特征。池化层则通过降采样的方式,减少特征图的尺寸,同时保留重要的特征信息。全连接层将特征图转化为一维向量,并通过神经网络的计算得出最终的分类结果。 通过手撕经典卷积神经网络的代码,我们可以更加深入地了解卷积神经网络的计算过程。该代码中的全连接层实际上就是指上述提到的全连接神经网络,它将最后一次卷积操作的输出作为输入,并通过神经网络的计算产生最终的输出结果。 总之,手撕经典卷积神经网络可以帮助我们更好地理解卷积神经网络的原理和计算过程。通过研究这个代码,我们可以深入了解卷积操作、池化操作和全连接操作在卷积神经网络中的应用,从而更好地应用和设计卷积神经网络模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值