nndl 作业6

卷积常用特征提取

实验过程注意认真体会 “特征提取” ,弄清楚为什么卷积能够提取特征

简单了解一下,大家常见的是二维卷积

平常生活中利用卷积可以识别检测,比如识别是猴子,马等,还有分类,利用一些特征判断是哪一类,最能接触到的就是人脸识别,通过提取每个人脸的特征,判断是否是这个人。

接下来在此章探索,学习卷积为什么能够提取特征
一、概念

用自己的语言描述 ”卷积、卷积核、特征图、特征选择、步长、填充、感受野“

卷积:卷积就是在输入数据上滑动一个窗口,跟上面的图一样,从而提取输入数据的特有的特征,如同你拿一块抹布在满是灰尘的地面上擦来擦去。

卷积核:是一个抹布,是一个矩阵,包含特定的权重和值(抹布上的清洁剂),通过在数据上滑动卷积核,提取特征。上面的红色和绿色的方框。

特征图:通过卷积后得到的特定特征,就是擦完地板后污渍和痕迹。

特征选择:挑选清洁剂的过程,最能解决问题的特征。

步长:提取时跳跃的步伐,可以一步一步擦拭,也可以大步大步,影响擦拭速度(提取的效率)和清洁程度(特征提取的精细程度)。

填充:擦拭地板之前,先在地面上喷洒一些水。这可以使得清洁剂更好地渗透到地板的缝隙中,清洁得更彻底。在卷积中,填充是在输入数据的边界上添加一些额外的像素点,以使得卷积操作能够更好地处理输入数据。

填充公式,输入尺寸N,卷积核尺寸F,填充P,步长S,

(N +2*P-F)/S+1。

例如

卷积两侧添加0的个数的公式为:
已知输入尺寸为4,卷积核尺寸为3,步长为1,填充大小为1
根据公式,输出尺寸为:
(4 - 3 + 2×1) / 1 + 1 = 4
所以,需要添加的0的个数为:
3 - 1 = 2
因此,卷积两侧需要添加2个0

感受野:通过卷积核的大小和步长决定的,如同人的视野,站的高望的远,影响提取到的特征的广度。

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

1.图1分别使用卷积核\left ( 1,-1 \right ),\bigl(\begin{smallmatrix} 1\\ -1\end{smallmatrix}\bigr)输出特征图。

import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt

featuremap = torch.tensor([[0, 0, 0, 255, 255, 255],
                           [0, 0, 0, 255, 255, 255],
                           [0, 0, 0, 255, 255, 255]])


# 确定卷积网络
class Cnet(torch.nn.Module):
    def __init__(self, filter, kshape):
        super(Cnet, self).__init__()
        filter = torch.reshape(filter, kshape)
        self.weight = torch.nn.Parameter(data=filter, requires_grad=False)

    def forward(self, featuremap):
        featuremap = F.conv2d(featuremap, self.weight, stride=1, padding=0)
        return featuremap


# 确定卷积层
filter = torch.tensor([-1, 1])
# 更改卷积层的形状适应卷积函数
kshape = (1, 1, 1, 2)
# 生成模型
model = Cnet(filter=filter, kshape=kshape)
# 更改图片的形状适应卷积层
featuremap = torch.reshape(featuremap, (1, 1, 3, 6))
output = model(featuremap)
output = torch.reshape(output, (3, 5))
plt.imshow(output, cmap='gray')
plt.show()

\left ( 1,-1 \right ) 

另外

 只需要改变卷积层形状适应卷积函数

2.图2使用 卷积核输出特征图

import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt

featuremap = torch.tensor([[0, 0, 0, 255, 255, 255],
                           [0, 0, 0, 255, 255, 255],
                           [0, 0, 0, 255, 255, 255],
                           [255, 255, 255, 0, 0, 0],
                           [255, 255, 255, 0, 0, 0],
                           [255, 255, 255, 0, 0, 0]])


# 确定卷积网络
class Cnet(torch.nn.Module):
    def __init__(self, filter, kshape):
        super(Cnet, self).__init__()
        filter = torch.reshape(filter, kshape)
        self.weight = torch.nn.Parameter(data=filter, requires_grad=False)

    def forward(self, featuremap):
        featuremap = F.conv2d(featuremap, self.weight, stride=1, padding=0)
        return featuremap


# 确定卷积层
filter = torch.tensor([-1, 1])
# 更改卷积层的形状适应卷积函数
kshape = (1, 1, 1, 2)
# 生成模型
model = Cnet(filter=filter, kshape=kshape)
# 更改图片的形状适应卷积层
featuremap = torch.reshape(featuremap, (1, 1, 6, 6))
output = model(featuremap)
output = torch.reshape(output, (6, 5))
plt.imshow(output, cmap='gray')
plt.show()

 

3.使用卷积核 \left ( 1,-1 \right )\bigl(\begin{smallmatrix} 1\\ -1\end{smallmatrix}\bigr)\bigl(\begin{smallmatrix} 1 &-1 \\ -1 & 1 \end{smallmatrix}\bigr)图3,输出特征图

import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt

featuremap = torch.tensor([[255, 255, 255, 255, 255, 255, 255, 255, 255],
                           [255, 0, 255, 255, 255, 255, 255, 0, 255],
                           [255, 255, 0, 255, 255, 255, 0, 255, 255],
                           [255, 255, 255, 0, 255, 0, 255, 255, 255],
                           [255, 255, 255, 255, 0, 255, 255, 255, 255],
                           [255, 255, 255, 0, 255, 0, 255, 255, 255],
                           [255, 255, 0, 255, 255, 255, 0, 255, 255],
                           [255, 0, 255, 255, 255, 255, 255, 0, 255],
                           [255, 255, 255, 255, 255, 255, 255, 255, 255], ])


# 确定卷积网络
class Cnet(torch.nn.Module):
    def __init__(self, filter, kshape):
        super(Cnet, self).__init__()
        filter = torch.reshape(filter, kshape)
        self.weight = torch.nn.Parameter(data=filter, requires_grad=False)

    def forward(self, featuremap):
        featuremap = F.conv2d(featuremap, self.weight, stride=1, padding=0)
        return featuremap


# 确定卷积层
filter = torch.tensor([-1, 1])
# 更改卷积层的形状适应卷积函数
kshape = (1, 1, 1, 2)
# 生成模型
model = Cnet(filter=filter, kshape=kshape)
# 更改图片的形状适应卷积层
featuremap = torch.reshape(featuremap, (1, 1, 9, 9))
output = model(featuremap)
output = torch.reshape(output, (9, 8))
plt.imshow(output, cmap='gray')
plt.show()

  

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

参考链接:https://setosa.io/ev/image-kernels/

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

im = Image.open('C:\\Users\\dell\\Desktop\\duolahuidu.jpg').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()

原图: 

边缘检测

锐化 出现了灰色,学习了一下老师发的

【NNDL作业】图像锐化后,为什么“蒙上了一层灰色”?

归一化问题,映射,大于255,小于0 

模糊

这个图效果不明显,如果大家做实验的原图找边缘较为清晰的 

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

 

边缘检测:边缘是图像的边缘(轮廓),目的是识别并突出这些轮廓,都使用特定的卷积核(也称为滤波器)来检测边缘。卷积核的主要特征是它们在水平和垂直方向上的权重不同,检测出水平和垂直的特征。

锐化:增强图像的细节和清晰度。通常使用一个包含正负值的卷积核来实现。这个卷积核的权重通常会在中心位置为正,而在其他位置为负。

模糊:减少图像的细节和噪声,通常使用一个包含正值的卷积核来实现。这个卷积核的权重通常会在中心位置为最大,并在逐渐远离中心的过程中逐渐减小。

实验总结:

在这个过程中,我的电脑原本有一张图,是彩色的,这个图需要转为灰度图,先前在matlab中学到过,在老师给的代码中的 

convert('L'),

是用来转为灰度图,pillow库中的函数

探究不同卷积核的作用时,实验过程中不清楚需要转为矩阵,这个矩阵到底怎么写,参考学长的代码才明白作业5:卷积 

卷积提取特征原理

通过卷积核在图像上滑动并执行卷积操作,从而提取出图像中的特征。卷积核是一个小的矩阵,它可以提取图像中的局部特征,例如边缘,在卷积过程中,卷积核会在图像上滑动,并对覆盖的局部区域进行卷积运算,从而得到一组特征映射图。这些特征映射图可以表达出图像中的特征 

 

 

参考文献:

NNDL 作业5:卷积

【动手学深度学习PyTorch版】13 卷积层的填充和步幅

CNN卷积神经网络学习笔记(特征提取)

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

其他的我已经标注 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值