NNDL 作业6 卷积

一、概念

  卷积:一种数学运算,多用于信号处理或图像处理中,有一维卷积、二维卷积。使用一个一维或二维矩阵,用滑动窗口,进行点积运算。通常卷积是需要翻转卷积核,但在神经网络中,卷积实际上是一种互相关操作。二者的唯一区别仅在于卷积核是否翻转,其特征提取能力等价,。

  卷积核:在卷积运算中使用的一个小矩阵,用于提取输入数据中的特征信息。在神经网络中,卷积核是在卷积层中用于提取图像特征的过滤器。

  特征图:卷积核通过对输入数据进行滑动窗口操作,将其与输入数据中的每个像素进行卷积计算,结果就是特征图。

  特征选择:从原始数据中,选择最相关的特征,这个过程就叫特征选择。卷积操作就是神经网络进行特征选择的过程。

  步长:卷积核每次滑动的时间间隔或者是像素间隔数。

  填充:在向量的两端进行进行补充。体现在图像上就是在图像的四周添加像素,通常是补零,也叫零填充。填充是为了不忽略边缘特征。

  感受野:特征图上的一个点对应输入图像上的区域。越往后,特征图的一个点对应的区域越大。感受野越大。

二、探究不同卷积核的作用

1、图一分别使用卷积核(1,-1)\binom{1}{-1},输出特征图。

2、图二分别使用卷积核(1,-1)\binom{1}{-1},输出特征图。

3、图一分别使用卷积核(1,-1)\binom{1}{-1}\bigl(\begin{smallmatrix} 1 , -1 \\ -1 , 1 \end{smallmatrix}\bigr),输出特征图。

        1、2、3实现过程:

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from torch import nn
from torch.autograd import Variable
import torch
img1=np.zeros([300,600],dtype='float32')
img1[:,300:]=255.0
plt.figure(1)
plt.subplot(1,3,1)
plt.imshow(img1.astype('uint8'),cmap='gray')
plt.title('original')
kernel1=np.array([1,-1],dtype='float32')
kernel2=np.array([1,-1],dtype='float32').reshape(2,1)

img1=torch.from_numpy(img1.reshape((1,1,img1.shape[0],img1.shape[1])))
conv1=nn.Conv2d(1,1,[1,2],bias=False)
conv2=nn.Conv2d(1,1,[2,1],bias=False)

kernel1=kernel1.reshape((1,1,1,2))
kernel2=kernel2.reshape((1,1,2,1))

conv1.weight.data=torch.from_numpy(kernel1)
edge1=conv1(Variable(img1))
img1_dealed=edge1.data.squeeze().numpy()

conv2.weight.data=torch.from_numpy(kernel2)
edge2=conv2(Variable(img1))
img1_dealed1=edge2.data.squeeze().numpy()

plt.subplot(1,3,2)
plt.imshow(img1_dealed.astype('uint8'),cmap='gray')
plt.title('1x2 kernel')
plt.subplot(1,3,3)
plt.imshow(img1_dealed1.astype('uint8'),cmap='gray')
plt.title('2x1 kernel')
plt.show()

plt.figure(2)
img2=np.zeros([600,600],dtype='float32')
img2[300:,0:300]=255
img2[:300,300:]=255
plt.subplot(1,3,1)
plt.imshow(img2.astype('uint8'),cmap='gray')
plt.title('original')
img2=torch.from_numpy(img2.reshape((1,1,img2.shape[0],img2.shape[1])))
edge1_1=conv1(Variable(img2))
img2_dealed=edge1_1.data.squeeze().numpy()
edge2_1=conv2(Variable(img2))
img2_dealed1=edge2_1.data.squeeze().numpy()
img2_dealed[0:300,299]=255.0
img2_dealed1[299,0:300]=255.0
plt.subplot(1,3,2)
plt.imshow(img2_dealed.astype('uint8'),cmap='gray')
plt.title('1x2 kernel')
plt.subplot(1,3,3)
plt.imshow(img2_dealed1.astype('uint8'),cmap='gray')
plt.title('2x1 kernel')
plt.show()
file_path=r"X.png"
img3=Image.open(file_path).convert('L')
img3=np.array(img3,dtype='float32')
plt.figure(3)
plt.subplot(2,2,1)
plt.imshow(img3.astype('uint8'),cmap='gray')
plt.title('original')
kernel3=np.array([[1,-1],[-1,1]],dtype='float32')
img3=torch.from_numpy(img3.reshape((1,1,img3.shape[0],img3.shape[1])))
conv3=nn.Conv2d(1,1,2,bias=False)
kernel3=kernel3.reshape((1,1,2,2))
conv3.weight.data=torch.from_numpy(kernel3)

ximg3_0=conv3(Variable(img3))
ximg3_0=ximg3_0.data.squeeze().numpy()
for i in range(ximg3_0.shape[0]):
    for j in range(ximg3_0.shape[1]):
        if ximg3_0[i,j]==-255.0:
            ximg3_0[i,j]=255.0
ximg3_1=conv1(Variable(img3))
ximg3_1=ximg3_1.data.squeeze().numpy()
for i in range(ximg3_1.shape[0]):
    for j in range(ximg3_1.shape[1]):
        if ximg3_1[i,j]==-255.0:
            ximg3_1[i,j]=255.0
ximg3_2=conv2(Variable(img3))
ximg3_2=ximg3_2.data.squeeze().numpy()
for i in range(ximg3_2.shape[0]):
    for j in range(ximg3_2.shape[1]):
        if ximg3_2[i,j]==-255.0:
            ximg3_2[i,j]=255.0
plt.subplot(2,2,2)
plt.imshow(ximg3_0.astype('uint8'),cmap='gray')
plt.title('2x2 kernel')
plt.subplot(2,2,3)
plt.imshow(ximg3_1.astype('uint8'),cmap='gray')
plt.title('1x2 kernel')
plt.subplot(2,2,4)
plt.imshow(ximg3_2.astype('uint8'),cmap='gray')
plt.title('2x1 kernel')
plt.show()


4、实现灰度图的边缘检测、锐化、模糊。

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
from PIL import Image
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
file_path = "cat.png"
im = Image.open(file_path).convert('L')
im = np.array(im,dtype='float32')
print(im.shape[0],im.shape[1])
plt.subplot(2,2,1)
plt.imshow(im.astype('uint8'),cmap='gray')
plt.title('原图')


im=torch.from_numpy(im.reshape((1,1,im.shape[0],im.shape[1])))
conv1=nn.Conv2d(1,1,3, bias=False)
conv2=nn.Conv2d(1,1,3,bias=False)
conv3=nn.Conv2d(1,1,3,bias=False)

sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 8, -1],
                         [-1, -1, -1]], dtype='float32')#边缘检测
sobel_kernel_sharpen=np.array([[0,-1,0],[-1,10,-1],[0,-1,0]],dtype='float32')#锐化
sobel_kernel_blur=np.array([[0.0625,0.125,0.0625],[0.125,0.25,0.125],[0.0625,0.0125,0.0625]],dtype='float32')#模糊
sobel_kernel=sobel_kernel.reshape((1, 1, 3, 3))
sobel_kernel_sharpen=sobel_kernel_sharpen.reshape((1,1,3,3))
sobel_kernel_blur=sobel_kernel_blur.reshape((1,1,3,3))

conv1.weight.data=torch.from_numpy(sobel_kernel)
edge1=conv1(Variable(im))
conv2.weight.data=torch.from_numpy(sobel_kernel_sharpen)
sharpen=conv2(Variable(im))
conv3.weight.data=torch.from_numpy(sobel_kernel_blur)
blur=conv3(Variable(im))

x=edge1.data.squeeze().numpy()
x1=sharpen.data.squeeze().numpy()
x2=blur.data.squeeze().numpy()

plt.subplot(2,2,2)
plt.imshow(x, cmap='gray')
plt.title('outline')
plt.subplot(2,2,3)
plt.imshow(x1,cmap='gray')
plt.title('sharpen')
plt.subplot(2,2,4)
plt.imshow(x2,cmap='gray')
plt.title('blur')
plt.show()

5、总结不同卷积核的特征和作用。

        \begin{pmatrix} 1 -1 \end{pmatrix}卷积核能够将纵向的分界线特征提取出来。

        \begin{pmatrix} 1\\ -1 \end{pmatrix}卷积核能够将横向分布的分界线特征提取出来。

        \bigl(\begin{smallmatrix} 1 , -1\\ -1 , 1 \end{smallmatrix}\bigr)卷积核能够将横向和纵向分布的分界线特征提取出来。

        这些卷积核会对图像中相邻像素之间的差异进行计算,从而突出显示出图像中的边界线。

总结:

它的原理是通过将卷积核对图像进行滑动操作,计算出每个像素与其周围像素的差异,从而提取出图像的特征。这种操作可以被视为加权相乘再相加计算的一种形式,其中卷积核定义了权重系数。也就是说,要提取什么样的特征,卷积核首先就要符合什么特征。卷积的关键也就是卷积核的选择。例如,在边缘检测任务中,我们可以选择一个包含边缘特征的卷积核,如[[1, -1], [-1, 1]],它可以检测出图像中的边缘。类似地,我们可以选择其他卷积核来提取其他类型的特征。

参考:

【23-24 秋学期】NNDL 作业6 卷积

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值