• NNDL 实验六 卷积神经网络


    目录

    5.1 卷积

    5.1.1 二维卷积运算

    5.1.2 二维卷积算子

    5.1.3 二维卷积的参数量和计算量

    5.1.4 感受野

    5.1.5 卷积的变种

    5.1.6 带步长和零填充的二维卷积算子

    5.1.7 使用卷积运算完成图像边缘检测任务

    选做题:实现1、2;阅读3、4、5


    卷积神经网络(Convolutional Neural Network,CNN)

    • 受生物学上感受野机制的启发而提出。
    • 一般是由卷积层、汇聚层和全连接层交叉堆叠而成的前馈神经网络
    • 有三个结构上的特性:局部连接、权重共享、汇聚
    • 具有一定程度上的平移、缩放和旋转不变性。
    • 和前馈神经网络相比,卷积神经网络的参数更少
    • 主要应用在图像和视频分析的任务上,其准确率一般也远远超出了其他的神经网络模型。
    • 近年来卷积神经网络也广泛地应用到自然语言处理、推荐系统等领域。

    5.1 卷积

    5.1.1 二维卷积运算

    ec87e69830004abcaa9eba13a6019b5d.png

    5.1.2 二维卷积算子

    在本书后面的实现中,算子都继承paddle.nn.Layer,并使用支持反向传播的飞桨API进行实现,这样我们就可以不用手工写backword()的代码实现。

    【使用pytorch实现自定义二维卷积算子】

    参考代码:

    1. import paddle
    2. import paddle.nn as nn
    3. class Conv2D(nn.Layer):
    4. def __init__(self, kernel_size,
    5. weight_attr=paddle.ParamAttr(initializer=nn.initializer.Assign(value=[[0., 1.],[2., 3.]]))):
    6. super(Conv2D, self).__init__()
    7. # 使用'paddle.create_parameter'创建卷积核
    8. # 使用'paddle.ParamAttr'进行参数初始化
    9. self.weight = paddle.create_parameter(shape=[kernel_size,kernel_size],
    10. dtype='float32',
    11. attr=weight_attr)
    12. def forward(self, X):
    13. """
    14. 输入:
    15. - X:输入矩阵,shape=[B, M, N],B为样本数量
    16. 输出:
    17. - output:输出矩阵
    18. """
    19. u, v = self.weight.shape
    20. output = paddle.zeros([X.shape[0], X.shape[1] - u + 1, X.shape[2] - v + 1])
    21. for i in range(output.shape[1]):
    22. for j in range(output.shape[2]):
    23. output[:, i, j] = paddle.sum(X[:, i:i+u, j:j+v]*self.weight, axis=[1,2])
    24. return output
    25. # 随机构造一个二维输入矩阵
    26. paddle.seed(100)
    27. inputs = paddle.to_tensor([[[1.,2.,3.],[4.,5.,6.],[7.,8.,9.]]])
    28. conv2d = Conv2D(kernel_size=2)
    29. outputs = conv2d(inputs)
    30. print("input: {}, \noutput: {}".format(inputs, outputs))

    5.1.3 二维卷积的参数量和计算量

    随着隐藏层神经元数量的变多以及层数的加深,

    使用全连接前馈网络处理图像数据时,参数量会急剧增加。

    如果使用卷积进行图像处理,相较于全连接前馈网络,参数量少了非常多。

    5.1.4 感受野

    465993b58fac42da92c8f1fd5516e67e.png

    6d358fa2ab694636a15f8ae7c3932273.png

    5.1.5 卷积的变种

    5.1.5.1 步长(Stride)

    0292a79b9ab24ff6bb58ec464ef0ae47.png

    5.1.5.2 零填充(Zero Padding)

    749365bb722d4c158080ef7bd90df469.png

    5.1.6 带步长和零填充的二维卷积算子

    从输出结果看出,使用3×3大小卷积,

    padding为1,

    stride=1时,模型的输出特征图与输入特征图保持一致;

    stride=2时,模型的输出特征图的宽和高都缩小一倍。

    【使用pytorch实现自定义带步长和零填充的二维卷积算子】

    参考代码

    1. class Conv2D(nn.Layer):
    2. def __init__(self, kernel_size, stride=1, padding=0,
    3. weight_attr=paddle.ParamAttr(initializer=nn.initializer.Constant(value=1.0))):
    4. super(Conv2D, self).__init__()
    5. self.weight = paddle.create_parameter(shape=[kernel_size,kernel_size],
    6. dtype='float32',
    7. attr=weight_attr)
    8. # 步长
    9. self.stride = stride
    10. # 零填充
    11. self.padding = padding
    12. def forward(self, X):
    13. # 零填充
    14. new_X = paddle.zeros([X.shape[0], X.shape[1]+2*self.padding, X.shape[2]+2*self.padding])
    15. new_X[:, self.padding:X.shape[1]+self.padding, self.padding:X.shape[2]+self.padding] = X
    16. u, v = self.weight.shape
    17. output_w = (new_X.shape[1] - u) // self.stride + 1
    18. output_h = (new_X.shape[2] - v) // self.stride + 1
    19. output = paddle.zeros([X.shape[0], output_w, output_h])
    20. for i in range(0, output.shape[1]):
    21. for j in range(0, output.shape[2]):
    22. output[:, i, j] = paddle.sum(
    23. new_X[:, self.stride*i:self.stride*i+u, self.stride*j:self.stride*j+v]*self.weight,
    24. axis=[1,2])
    25. return output
    26. inputs = paddle.randn(shape=[2, 8, 8])
    27. conv2d_padding = Conv2D(kernel_size=3, padding=1)
    28. outputs = conv2d_padding(inputs)
    29. print("When kernel_size=3, padding=1 stride=1, input's shape: {}, output's shape: {}".format(inputs.shape, outputs.shape))
    30. conv2d_stride = Conv2D(kernel_size=3, stride=2, padding=1)
    31. outputs = conv2d_stride(inputs)
    32. print("When kernel_size=3, padding=1 stride=2, input's shape: {}, output's shape: {}".format(inputs.shape, outputs.shape))

    5.1.7 使用卷积运算完成图像边缘检测任务

    【使用pytorch实现图像边缘检测】

    a60f3ca00eec4703a859555d36d53fab.jpeg

    7a42f97f0e53456a958c1b8f31f6e2f0.png

    参考代码

    1. %matplotlib inline
    2. import matplotlib.pyplot as plt
    3. from PIL import Image
    4. import numpy as np
    5. # 读取图片
    6. img = Image.open('./number.jpg').resize((256,256))
    7. # 设置卷积核参数
    8. w = np.array([[-1,-1,-1], [-1,8,-1], [-1,-1,-1]], dtype='float32')
    9. # 创建卷积算子,卷积核大小为3x3,并使用上面的设置好的数值作为卷积核权重的初始化参数
    10. conv = Conv2D(kernel_size=3, stride=1, padding=0,
    11. weight_attr=paddle.ParamAttr(initializer=nn.initializer.Assign(value=w)))
    12. # 将读入的图片转化为float32类型的numpy.ndarray
    13. inputs = np.array(img).astype('float32')
    14. print("bf to_tensor, inputs:",inputs)
    15. # 将图片转为Tensor
    16. inputs = paddle.to_tensor(inputs)
    17. print("bf unsqueeze, inputs:",inputs)
    18. inputs = paddle.unsqueeze(inputs, axis=0)
    19. print("af unsqueeze, inputs:",inputs)
    20. outputs = conv(inputs)
    21. outputs = outputs.numpy()
    22. # 可视化结果
    23. plt.figure(figsize=(8, 4))
    24. f = plt.subplot(121)
    25. f.set_title('input image', fontsize=15)
    26. plt.imshow(img)
    27. f = plt.subplot(122)
    28. f.set_title('output feature map', fontsize=15)
    29. plt.imshow(outputs.squeeze(), cmap='gray')
    30. plt.savefig('conv-vis.pdf')
    31. plt.show()

     


    选做题

    Pytorch实现1、2;阅读3、4、5写体会。


    边缘检测系列1:传统边缘检测算子 - 飞桨AI Studio

    实现一些传统边缘检测算子,如:Roberts、Prewitt、Sobel、Scharr、Kirsch、Robinson、Laplacian


    边缘检测系列2:简易的 Canny 边缘检测器 - 飞桨AI Studio

    实现的简易的 Canny 边缘检测算法


    边缘检测系列3:【HED】 Holistically-Nested 边缘检测 - 飞桨AI Studio

    复现论文 Holistically-Nested Edge Detection,发表于 CVPR 2015 

    一个基于深度学习的端到端边缘检测模型

    08e50a26da564a72aa021cf450784d55.jpeg

    a4facf95480645b58a6d2148366ae764.jpeg


    边缘检测系列4:【RCF】基于更丰富的卷积特征的边缘检测 - 飞桨AI Studio (baidu.com)

    复现论文 Richer Convolutional Features for Edge Detection,CVPR 2017 发表

    一个基于更丰富的卷积特征的边缘检测模型 【RCF】。

    5bad44d0f55645d3bf3a4918da303075.jpeg

    76fd7ab6979e4bdea26c475806e40bc5.jpeg


    边缘检测系列5:【CED】添加了反向细化路径的 HED 模型 - 飞桨AI Studio (baidu.com)

    Crisp Edge Detection(CED)模型是前面介绍过的 HED 模型的另一种改进模型

    1f2b9e9a6eca4db7bcc05d242b739ed8.jpeg

    5ecd3e1f5cb54cecb1e4ca6f815cda22.jpeg


    NNDL 实验5(上) - HBU_DAVID - 博客园 (cnblogs.com)

    NNDL 实验5(下) - HBU_DAVID - 博客园 (cnblogs.com)

    6. 卷积神经网络 — 动手学深度学习 2.0.0-beta1 documentation (d2l.ai)

    7. 现代卷积神经网络 — 动手学深度学习 2.0.0-beta1 documentation (d2l.ai)

  • 相关阅读:
    数字孪生推动军营智慧化管理,军事化应用战场空间可视化解决方案
    2023年Vue开发中的8个最佳工具
    Linux进程管理和计划任务与系统备份恢复
    【Linux高性能服务器编程】前篇
    第十一届中国云计算标准和应用大会 | 云计算国家标准及白皮书系列发布 华云数据全面参与编制
    Java 对象内存占用分析
    石油化工行业能源管理平台,让能源管理更简单,更高效
    Git操作命令
    golang问题
    异步机制的简单实现
  • 原文地址:https://blog.csdn.net/qq_38975453/article/details/126521281