一、概念
用自己的语言描述“卷积、卷积核、特征图、特征选择、步长、填充、感受野”。
卷积:卷积是分析数学中的一种重要的运算,主要用于图像数据处理。卷积运算过程需要把数据和卷积核进行运算。卷积得到的结果是特征图。
卷积核:它是一个小矩阵,其中包含了待学习的权重参数。卷积核的大小通常是正方形的。
特征图:特征图(Feature Map)是经过卷积操作得到的一组二维或三维数组;特征图通常用于表示神经网络中不同层级的抽象特征,大小和数量取决于卷积操作的参数设置。
特征选择:在机器学习或数据挖掘中,从原始的特征集合中选择最有用的特征子集作为模型输入的过程。
步长:卷积操作中用于控制滑动窗口移动的距离或卷积核每次移动的步长大小,步长决定了卷积操作在输入数据上进行滑动的速度和间隔。
填充:输入数据周围添加额外的像素或值,以便在进行卷积操作时保持输出特征图的尺寸与输入数据的尺寸相同或类似。
感受野:神经网络中的一个神经元对应输入数据的区域大小。
二、探究不同卷积核的作用
【精选】NNDL 作业5:卷积_cmap='gray-CSDN博客
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch import nn
#二位互相关运算
def corr2d(X,K): #@save
h,w=K.shape #K用来接受卷积核的高度和宽度
Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1))#创建一个全零的输出张量Y,输入X的高度减去卷积核高度加1,宽度减去卷积核宽度加1
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):#使用两个嵌套的循环遍历输出张量Y的每个位置
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
#创建一个半黑半白的图
pic=torch.zeros((7,6)) #定义一个7*6的全零矩阵
x=pic
pic[:,3:6]=255 #是矩阵中三到六列的数据变成255
print(pic)
plt.imshow(pic,cmap='Greys_r') #输出图片,cmap='Greys_r'申明这是灰度图
K=torch.tensor([[1,-1]])#定义卷积核,将其宽度调整为1
jieguo=corr2d(pic,K) #将pic与K卷积核进行卷积运算
print(jieguo)
plt.imshow(jieguo,cmap='Greys_r')
plt.show()
输出结果:
卷积前后的特征矩阵:
卷积前特征图:
卷积后:
卷积核(1 , -1)
卷积核:
K=torch.tensor([[1,-1]])#定义卷积核,将其宽度调整为1
jieguo=corr2d(pic,K.T) #将pic与K卷积核进行卷积运算
2. 图2分别使用卷积核,
输出特征图
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch import nn
#二位互相关运算
def corr2d(X,K): #@save
h,w=K.shape #K用来接受卷积核的高度和宽度
Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1))#创建一个全零的输出张量Y,输入X的高度减去卷积核高度加1,宽度减去卷积核宽度加1
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):#使用两个嵌套的循环遍历输出张量Y的每个位置
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
#创建一个半黑半白的图
pic=torch.zeros((14,12)) #定义一个14*12的全零矩阵
x=pic
x[7:14,0:6]=255
x[0:7,6:12]=255
print(pic)
plt.imshow(x,cmap='Greys_r') #输出图片,cmap='Greys_r'申明这是灰度图
plt.show()
K=torch.tensor([[1,-1]])#定义卷积核,将其宽度调整为1
jieguo=corr2d(x,K) #将pic与K卷积核进行卷积运算
print(jieguo)
plt.imshow(jieguo,cmap='Greys_r')
plt.show()
运行结果:
原图:
卷积和(1 -1):
卷积核:
3. 图3分别使用卷积核,
,
,输出特征图
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch import nn
#二位互相关运算
def corr2d(X,K): #@save
h,w=K.shape #K用来接受卷积核的高度和宽度
Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1))#创建一个全零的输出张量Y,输入X的高度减去卷积核高度加1,宽度减去卷积核宽度加1
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):#使用两个嵌套的循环遍历输出张量Y的每个位置
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
pic=torch.zeros((9,9))
x=pic
for i in range(0,7):
x[i+1,i+1]=255
x[i+1,7-i]=255
plt.imshow(x,cmap='Greys_r') #输出图片,cmap='Greys_r'申明这是灰度图
plt.show()
K=torch.tensor([[1,-1]])#定义卷积核,将其宽度调整为1
jieguo=corr2d(x,K) #将pic与K卷积核进行卷积运算
print(jieguo)
plt.imshow(jieguo,cmap='Greys_r')
plt.show()
结果:
原图:
卷积核(1 -1):
卷积核:
卷积核:
K=torch.tensor([[1,-1],
[-1,1]])
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 # 用来正常显示负号 #有中文出现的情况,需要u'内容
# https://blog.csdn.net/weixin_40123108/article/details/83510592
file_path = '风景.jpg'
im = Image.open(file_path).convert('L') # 读入一张灰度图的图片
im = np.array(im, dtype='float32') # 将其转换为一个矩阵
print(im.shape[0], im.shape[1])
plt.imshow(im.astype('uint8'), cmap='gray') # 可视化图片
plt.title('原图')
plt.show()
im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))
conv1 = nn.Conv2d(1, 1, 3, bias=False) # 定义卷积
sobel_kernel = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]], dtype='float32') # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3)) # 适配卷积的输入输出
conv1.weight.data = torch.from_numpy(sobel_kernel) # 给卷积的 kernel 赋值
edge1 = conv1(Variable(im)) # 作用在图片上
x = edge1.data.squeeze().numpy()
print(x.shape) # 输出大小
plt.imshow(x, cmap='gray')
plt.show()
锐化:
# -*- coding: utf-8 -*-
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 # 用来正常显示负号 #有中文出现的情况,需要u'内容
# https://blog.csdn.net/weixin_40123108/article/details/83510592
file_path = '风景.jpg'
im = Image.open(file_path).convert('L') # 读入一张灰度图的图片
im = np.array(im, dtype='float32') #将其转换为一个矩阵
print(im.shape[0], im.shape[1])
plt.imshow(im.astype('uint8'), cmap='gray') # 可视化图片
plt.show()
im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))
conv1 = nn.Conv2d(1, 1, 3, bias=False) # 定义卷积
sobel_kernel = np.array([[0, -1, 0], [-1, 5 ,-1], [-1, 5, -1]], dtype='float32') # 定义锐化
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3)) # 适配卷积的输入输出
conv1.weight.data = torch.from_numpy(sobel_kernel) # 给卷积的 kernel 赋值
edge1 = conv1(Variable(im)) # 作用在图片上
x = edge1.data.squeeze().numpy()
print(x.shape) #输出大小
plt.imshow(x, cmap='gray')
plt.show()
模糊:
# -*- coding: utf-8 -*-
import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
from PIL import Image
import matplotlib.pyplot as plt
import torch.nn.functional as F
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 #有中文出现的情况,需要u'内容
# https://blog.csdn.net/weixin_40123108/article/details/83510592
file_path = '风景.jpg'
im = Image.open(file_path).convert('L') # 读入一张灰度图的图片
im = np.array(im, dtype='float32') #将其转换为一个矩阵
print(im.shape[0], im.shape[1])
plt.imshow(im.astype('uint8'), cmap='gray') # 可视化图片
plt.show()
# 将图片转换为PyTorch的Tensor格式,并将通道数设置为1
im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))
# 对原图使用最大池化
small_im2 = F.max_pool2d(Variable(im), 2, 2)
small_im2 = small_im2.data.squeeze().numpy()
plt.imshow(small_im2, cmap='gray')
plt.show()
5. 总结不同卷积核的特征和作用。
-
锐化卷积核:
- 特征:增强图像的边缘和细节。
- 作用:通过对图像进行锐化,使得图像边缘更加清晰。
-
模糊卷积核:
- 特征:模糊图像,减少图像的细节和噪声。
- 作用:通过模糊图像,可以减少图像中的噪声或者实现一种特殊的视觉效果。
-
边缘检测卷积核:
- 特征:检测图像中的边缘。
- 作用:通过识别图像中的边缘,可以提取物体的轮廓和形状。
-
浮雕效果卷积核:
- 特征:给图像添加浮雕效果,突出物体的轮廓。
- 作用:通过将图像中的高光和阴影区域突出显示,创建出一种凹凸感,使图像看起来更加立体。
-
高斯模糊卷积核:
- 特征:模糊图像,平滑细节。
- 作用:通过减少图像中的高频细节,达到平滑图像的效果。