一、卷积、卷积核、多通道、特征图、特征选择概念。

卷积:是通过两个函数f和g生成第三个函数的一种数学运算,其本质是一种特殊的积分变换,表征函数f与g经过翻转和平移的重叠部分函数值乘积对重叠长度的积分。
卷积核:卷积核实际上是一个滤波器,在卷积神经网络中其参数是可学习的,对于一个通道数为c的输入特征图,需要的卷积核的size为(c, k, k),其中k是卷积核长宽。卷积核的可学习参数还有一个bias,其size为(c, ),即卷积核的每个channel对应一个bias。
多通道:假设输入特征图channel为m,要求输出特征图channel为n,则需要n个size为(m, k, k)的卷积核。
特征选择:不同的卷积核对输入特征图上不同的pattern的响应不同,所以一个卷积核可以输出一张某pattern的响应强度特征图。

二、编程实现:

1.经典卷积核,实现灰度图的边缘检测、锐化、模糊
运行结果:

原图(图片大小为659 X 658):

[-1, -1, -1]

[-1, 8, -1]

[-1, -1, -1]

cnn 卷积和池化 cnn 卷积核怎么定义_深度学习


边缘检测:

cnn 卷积和池化 cnn 卷积核怎么定义_人工智能_02

锐化;

cnn 卷积和池化 cnn 卷积核怎么定义_cnn_03

模糊:

cnn 卷积和池化 cnn 卷积核怎么定义_卷积核_04


2.调整经典卷积核参数,测试并总结

调整:

[-10, -10, -10]

[-10, 10, -10]

[-5, -5, -5]

cnn 卷积和池化 cnn 卷积核怎么定义_人工智能_05

3.使用不同尺寸图片,测试并总结

图片大小改为200x186

cnn 卷积和池化 cnn 卷积核怎么定义_卷积核_06


边缘检测:

cnn 卷积和池化 cnn 卷积核怎么定义_深度学习_07

锐化:

cnn 卷积和池化 cnn 卷积核怎么定义_cnn_08

模糊:

cnn 卷积和池化 cnn 卷积核怎么定义_cnn_09

4.尝试彩色图片边缘检测

im = Image.open(file_path).convert('L')

改成

im = Image.open(file_path).convert('RGB')

cnn 卷积和池化 cnn 卷积核怎么定义_cnn 卷积和池化_10

三、源代码:

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'内容
# 
file_path = 'xi.jpg'
im = Image.open(file_path).convert('L')  # 读入一张灰度图的图片

# im = im.resize((200,186))  # 改变图片尺寸

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([[0, -1, 0],
#                         [-1, 5, -1],
#                        [0, -1, 0]], dtype='float32')  # 定义轮廓检测算子
#边缘检测
sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 5, -1],
                         [-1, -1, -1]], dtype='float32')  # 定义轮廓检测算子
#模糊
# sobel_kernel = np.array( [[0.0625, 0.125, 0.0625],
#                          [0.125, 0.25, 0.125],
#                          [0.0625, 0.125, 0.0625]], 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()