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

在本书后面的实现中,算子都继承,并使用支持反向传播的paddle.nn.Layer飞桨API进行实现,这样我们就可以不用手工写backword()的代码实现。
【使用pytorch实现自定义二维卷积算子】
参考代码:
- import paddle
- import paddle.nn as nn
-
- class Conv2D(nn.Layer):
- def __init__(self, kernel_size,
- weight_attr=paddle.ParamAttr(initializer=nn.initializer.Assign(value=[[0., 1.],[2., 3.]]))):
- super(Conv2D, self).__init__()
- # 使用'paddle.create_parameter'创建卷积核
- # 使用'paddle.ParamAttr'进行参数初始化
- self.weight = paddle.create_parameter(shape=[kernel_size,kernel_size],
- dtype='float32',
- attr=weight_attr)
- def forward(self, X):
- """
- 输入:
- - X:输入矩阵,shape=[B, M, N],B为样本数量
- 输出:
- - output:输出矩阵
- """
- u, v = self.weight.shape
- output = paddle.zeros([X.shape[0], X.shape[1] - u + 1, X.shape[2] - v + 1])
- for i in range(output.shape[1]):
- for j in range(output.shape[2]):
- output[:, i, j] = paddle.sum(X[:, i:i+u, j:j+v]*self.weight, axis=[1,2])
- return output
-
- # 随机构造一个二维输入矩阵
- paddle.seed(100)
- inputs = paddle.to_tensor([[[1.,2.,3.],[4.,5.,6.],[7.,8.,9.]]])
-
- conv2d = Conv2D(kernel_size=2)
- outputs = conv2d(inputs)
- print("input: {}, \noutput: {}".format(inputs, outputs))
-
随着隐藏层神经元数量的变多以及层数的加深,
使用全连接前馈网络处理图像数据时,参数量会急剧增加。
如果使用卷积进行图像处理,相较于全连接前馈网络,参数量少了非常多。


5.1.5.1 步长(Stride)

5.1.5.2 零填充(Zero Padding)

从输出结果看出,使用3×3大小卷积,
padding为1,
当stride=1时,模型的输出特征图与输入特征图保持一致;
当stride=2时,模型的输出特征图的宽和高都缩小一倍。
【使用pytorch实现自定义带步长和零填充的二维卷积算子】
参考代码
- class Conv2D(nn.Layer):
- def __init__(self, kernel_size, stride=1, padding=0,
- weight_attr=paddle.ParamAttr(initializer=nn.initializer.Constant(value=1.0))):
- super(Conv2D, self).__init__()
- self.weight = paddle.create_parameter(shape=[kernel_size,kernel_size],
- dtype='float32',
- attr=weight_attr)
- # 步长
- self.stride = stride
- # 零填充
- self.padding = padding
-
- def forward(self, X):
- # 零填充
- new_X = paddle.zeros([X.shape[0], X.shape[1]+2*self.padding, X.shape[2]+2*self.padding])
- new_X[:, self.padding:X.shape[1]+self.padding, self.padding:X.shape[2]+self.padding] = X
- u, v = self.weight.shape
- output_w = (new_X.shape[1] - u) // self.stride + 1
- output_h = (new_X.shape[2] - v) // self.stride + 1
- output = paddle.zeros([X.shape[0], output_w, output_h])
- for i in range(0, output.shape[1]):
- for j in range(0, output.shape[2]):
- output[:, i, j] = paddle.sum(
- new_X[:, self.stride*i:self.stride*i+u, self.stride*j:self.stride*j+v]*self.weight,
- axis=[1,2])
- return output
-
- inputs = paddle.randn(shape=[2, 8, 8])
- conv2d_padding = Conv2D(kernel_size=3, padding=1)
- outputs = conv2d_padding(inputs)
- print("When kernel_size=3, padding=1 stride=1, input's shape: {}, output's shape: {}".format(inputs.shape, outputs.shape))
- conv2d_stride = Conv2D(kernel_size=3, stride=2, padding=1)
- outputs = conv2d_stride(inputs)
- print("When kernel_size=3, padding=1 stride=2, input's shape: {}, output's shape: {}".format(inputs.shape, outputs.shape))
【使用pytorch实现图像边缘检测】


参考代码
- %matplotlib inline
- import matplotlib.pyplot as plt
- from PIL import Image
- import numpy as np
-
- # 读取图片
- img = Image.open('./number.jpg').resize((256,256))
-
- # 设置卷积核参数
- w = np.array([[-1,-1,-1], [-1,8,-1], [-1,-1,-1]], dtype='float32')
- # 创建卷积算子,卷积核大小为3x3,并使用上面的设置好的数值作为卷积核权重的初始化参数
- conv = Conv2D(kernel_size=3, stride=1, padding=0,
- weight_attr=paddle.ParamAttr(initializer=nn.initializer.Assign(value=w)))
-
- # 将读入的图片转化为float32类型的numpy.ndarray
- inputs = np.array(img).astype('float32')
- print("bf to_tensor, inputs:",inputs)
- # 将图片转为Tensor
- inputs = paddle.to_tensor(inputs)
- print("bf unsqueeze, inputs:",inputs)
- inputs = paddle.unsqueeze(inputs, axis=0)
- print("af unsqueeze, inputs:",inputs)
- outputs = conv(inputs)
- outputs = outputs.numpy()
- # 可视化结果
- plt.figure(figsize=(8, 4))
- f = plt.subplot(121)
- f.set_title('input image', fontsize=15)
- plt.imshow(img)
- f = plt.subplot(122)
- f.set_title('output feature map', fontsize=15)
- plt.imshow(outputs.squeeze(), cmap='gray')
- plt.savefig('conv-vis.pdf')
- 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
一个基于深度学习的端到端边缘检测模型。


边缘检测系列4:【RCF】基于更丰富的卷积特征的边缘检测 - 飞桨AI Studio (baidu.com)
复现论文 Richer Convolutional Features for Edge Detection,CVPR 2017 发表
一个基于更丰富的卷积特征的边缘检测模型 【RCF】。


边缘检测系列5:【CED】添加了反向细化路径的 HED 模型 - 飞桨AI Studio (baidu.com)
Crisp Edge Detection(CED)模型是前面介绍过的 HED 模型的另一种改进模型


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